Skip to content

Commit

Permalink
seccomp: allow specifying a custom profile with --privileged
Browse files Browse the repository at this point in the history
`--privileged --security-opt seccomp=<CUSTOM.json>` was ignoring
`<CUSTOM.json>`.

Fix issue 47499

Signed-off-by: Akihiro Suda <akihiro.suda.cz@hco.ntt.co.jp>
  • Loading branch information
AkihiroSuda committed May 9, 2024
1 parent 4554d87 commit 9db3f21
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 4 deletions.
6 changes: 5 additions & 1 deletion daemon/seccomp_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ func WithSeccomp(daemon *Daemon, c *container.Container) coci.SpecOpts {
return nil
}
if c.HostConfig.Privileged {
return nil
var err error
if c.SeccompProfile != "" {
s.Linux.Seccomp, err = seccomp.LoadProfile(c.SeccompProfile, s)
}
return err
}
if !daemon.RawSysInfo().Seccomp {
if c.SeccompProfile != "" && c.SeccompProfile != dconfig.SeccompProfileDefault {
Expand Down
15 changes: 12 additions & 3 deletions daemon/seccomp_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ func TestWithSeccomp(t *testing.T) {
outSpec: oci.DefaultLinuxSpec(),
},
{
comment: "privileged container w/ custom profile runs unconfined",
// Prior to Docker v27, it had resulted in unconfined.
// https://github.com/moby/moby/pull/47500
comment: "privileged container w/ custom profile",
daemon: &Daemon{
sysInfo: &sysinfo.SysInfo{Seccomp: true},
},
Expand All @@ -50,8 +52,15 @@ func TestWithSeccomp(t *testing.T) {
Privileged: true,
},
},
inSpec: oci.DefaultLinuxSpec(),
outSpec: oci.DefaultLinuxSpec(),
inSpec: oci.DefaultLinuxSpec(),
outSpec: func() coci.Spec {
s := oci.DefaultLinuxSpec()
profile := &specs.LinuxSeccomp{
DefaultAction: specs.LinuxSeccompAction("SCMP_ACT_LOG"),
}
s.Linux.Seccomp = profile
return s
}(),
},
{
comment: "privileged container w/ default runs unconfined",
Expand Down
45 changes: 45 additions & 0 deletions integration/container/run_linux_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,51 @@ func TestWorkingDirNormalization(t *testing.T) {

assert.Check(t, is.Equal(inspect.Config.WorkingDir, "/tmp"))
})
}
}

func TestSeccomp(t *testing.T) {
skip.If(t, testEnv.DaemonInfo.OSType != "linux")

ctx := setupTest(t)
apiClient := testEnv.APIClient()

const confined = `{
"defaultAction": "SCMP_ACT_ALLOW",
"syscalls": [ { "names": [ "chown" ], "action": "SCMP_ACT_ERRNO" } ]
}
`
type testCase struct {
ops []func(*container.TestContainerConfig)
expectedExitCode int
}
testCases := []testCase{
{
ops: nil,
expectedExitCode: 0,
},
{
ops: []func(*container.TestContainerConfig){container.WithPrivileged(true)},
expectedExitCode: 0,
},
{
ops: []func(*container.TestContainerConfig){container.WithSecurityOpt("seccomp=" + confined)},
expectedExitCode: 1,
},
{
// A custom profile should be still enabled, even when --privileged is set
// https://github.com/moby/moby/issues/47499
ops: []func(*container.TestContainerConfig){container.WithPrivileged(true), container.WithSecurityOpt("seccomp=" + confined)},
expectedExitCode: 1,
},
}
for _, tc := range testCases {
cID := container.Run(ctx, t, apiClient, tc.ops...)
res, err := container.Exec(ctx, apiClient, cID, []string{"chown", "42", "/bin/true"})
assert.NilError(t, err)
assert.Equal(t, tc.expectedExitCode, res.ExitCode)
if tc.expectedExitCode != 0 {
assert.Check(t, is.Contains(res.Stderr(), "Operation not permitted"))
}
}
}

0 comments on commit 9db3f21

Please sign in to comment.