Skip to content

Commit c7f6419

Browse files
fengwei0328k8s-infra-cherrypick-robot
authored andcommitted
Fix privileged container sysfs can't be rw because pod is ro by default
Signed-off-by: fengwei0328 <[email protected]>
1 parent 67bb32a commit c7f6419

3 files changed

Lines changed: 120 additions & 0 deletions

File tree

integration/container_stats_test.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -428,3 +428,83 @@ func testStats(t *testing.T,
428428
require.NotEmpty(t, s.GetWritableLayer().GetInodesUsed().GetValue())
429429
}
430430
}
431+
432+
func TestContainerSysfsStatsWithPrivilegedPod(t *testing.T) {
433+
if goruntime.GOOS == "windows" {
434+
t.Skip("Doesn't care about filesystem properties on windows")
435+
}
436+
testImage := images.Get(images.BusyBox)
437+
testcases := []struct {
438+
name string
439+
privilegedPod, privilegedContainer bool
440+
expectedSysfsOption, expectedErr string
441+
}{
442+
{
443+
name: "sandbox and container with privileged=true, sysfs is rw",
444+
privilegedPod: true,
445+
privilegedContainer: true,
446+
expectedSysfsOption: "rw",
447+
},
448+
{
449+
name: "sandbox with privileged=true, and container with privileged=false, sysfs is ro",
450+
privilegedPod: true,
451+
privilegedContainer: false,
452+
expectedSysfsOption: "ro",
453+
},
454+
{
455+
name: "sandbox and container with privileged=false, sysfs is ro",
456+
privilegedPod: false,
457+
privilegedContainer: false,
458+
expectedSysfsOption: "ro",
459+
},
460+
{
461+
name: "sandbox with privileged=false, and container with privileged=true, create container failed",
462+
privilegedPod: false,
463+
privilegedContainer: true,
464+
expectedErr: "failed to generate spec opts: no privileged container allowed in sandbox",
465+
},
466+
}
467+
for _, test := range testcases {
468+
t.Run(test.name, func(t *testing.T) {
469+
EnsureImageExists(t, testImage)
470+
sb, sbConfig := PodSandboxConfigWithCleanup(
471+
t,
472+
"sandbox",
473+
"sysfs-stats-with-privileged",
474+
WithPodSecurityContext(test.privilegedPod),
475+
)
476+
cnConfig := ContainerConfig(
477+
"container",
478+
testImage,
479+
WithCommand("sh", "-c", "top"),
480+
WithSecurityContext(test.privilegedContainer),
481+
)
482+
cn, err := runtimeService.CreateContainer(sb, cnConfig, sbConfig)
483+
if test.expectedErr != "" && err != nil {
484+
assert.Contains(t, err.Error(), test.expectedErr)
485+
return
486+
}
487+
assert.NoError(t, err)
488+
defer func() {
489+
if test.expectedErr == "" {
490+
assert.NoError(t, runtimeService.RemoveContainer(cn))
491+
}
492+
}()
493+
494+
t.Log("Start the container")
495+
require.NoError(t, runtimeService.StartContainer(cn))
496+
defer func() {
497+
assert.NoError(t, runtimeService.StopContainer(cn, 10))
498+
}()
499+
500+
t.Logf("Execute cmd in container by sync")
501+
mountinfo, _, err := runtimeService.ExecSync(cn, []string{
502+
"sh",
503+
"-c",
504+
"mount |grep sysfs",
505+
}, 10)
506+
assert.NoError(t, err)
507+
assert.Contains(t, string(mountinfo), test.expectedSysfsOption)
508+
})
509+
}
510+
}

integration/main_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,19 @@ func WithPodLabels(kvs map[string]string) PodSandboxOpts {
218218
}
219219
}
220220

221+
// WithSecurityContext set container privileged.
222+
func WithPodSecurityContext(privileged bool) PodSandboxOpts {
223+
return func(p *runtime.PodSandboxConfig) {
224+
if p.Linux == nil {
225+
p.Linux = &runtime.LinuxPodSandboxConfig{}
226+
}
227+
if p.Linux.SecurityContext == nil {
228+
p.Linux.SecurityContext = &runtime.LinuxSandboxSecurityContext{}
229+
}
230+
p.Linux.SecurityContext.Privileged = privileged
231+
}
232+
}
233+
221234
// PodSandboxConfig generates a pod sandbox config for test.
222235
func PodSandboxConfig(name, ns string, opts ...PodSandboxOpts) *runtime.PodSandboxConfig {
223236
var cgroupParent string
@@ -462,6 +475,19 @@ func WithSupplementalGroups(gids []int64) ContainerOpts {
462475
}
463476
}
464477

478+
// WithSecurityContext set container privileged.
479+
func WithSecurityContext(privileged bool) ContainerOpts {
480+
return func(c *runtime.ContainerConfig) {
481+
if c.Linux == nil {
482+
c.Linux = &runtime.LinuxContainerConfig{}
483+
}
484+
if c.Linux.SecurityContext == nil {
485+
c.Linux.SecurityContext = &runtime.LinuxContainerSecurityContext{}
486+
}
487+
c.Linux.SecurityContext.Privileged = privileged
488+
}
489+
}
490+
465491
// WithDevice adds a device mount.
466492
func WithDevice(containerPath, hostPath, permissions string) ContainerOpts {
467493
return func(c *runtime.ContainerConfig) {

internal/cri/server/podsandbox/sandbox_run.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"context"
2121
"errors"
2222
"fmt"
23+
"path/filepath"
2324

2425
"github.com/containerd/log"
2526
"github.com/containerd/nri"
@@ -136,6 +137,7 @@ func (c *Controller) Start(ctx context.Context, id string) (cin sandbox.Controll
136137
if err != nil {
137138
return cin, fmt.Errorf("failed to generate sandbox container spec: %w", err)
138139
}
140+
139141
log.G(ctx).WithField("podsandboxid", id).Debugf("sandbox container spec: %#+v", spew.NewFormatter(spec))
140142

141143
metadata.ProcessLabel = spec.Process.SelinuxLabel
@@ -155,6 +157,18 @@ func (c *Controller) Start(ctx context.Context, id string) (cin sandbox.Controll
155157
// If privileged don't set selinux label, but we still record the MCS label so that
156158
// the unused label can be freed later.
157159
spec.Process.SelinuxLabel = ""
160+
// If privileged is enabled, sysfs should have the rw attribute
161+
for i, k := range spec.Mounts {
162+
if filepath.Clean(k.Destination) == "/sys" {
163+
for j, v := range spec.Mounts[i].Options {
164+
if v == "ro" {
165+
spec.Mounts[i].Options[j] = "rw"
166+
break
167+
}
168+
}
169+
break
170+
}
171+
}
158172
}
159173

160174
// Generate spec options that will be applied to the spec later.

0 commit comments

Comments
 (0)