Skip to content

Commit

Permalink
Fix daemon.json and daemon --seccomp-profile not accepting "unconfined"
Browse files Browse the repository at this point in the history
Commit b237189 implemented an option to
set the default seccomp profile in the daemon configuration. When that PR
was reviewed, it was discussed to have the option accept the path to a custom
profile JSON file; moby#26276 (comment)

However, in the implementation, the special "unconfined" value was not taken into
account. The "unconfined" value is meant to disable seccomp (more factually:
run with an empty profile).

While it's likely possible to achieve this by creating a file with an an empty
(`{}`) profile, and passing the path to that file, it's inconsistent with the
`--security-opt seccomp=unconfined` option on `docker run` and `docker create`,
which is both confusing, and makes it harder to use (especially on Docker Desktop,
where there's no direct access to the VM's filesystem).

This patch adds the missing check for the special "unconfined" value.

Co-authored-by: Tianon Gravi <[email protected]>
Signed-off-by: Sebastiaan van Stijn <[email protected]>
  • Loading branch information
thaJeztah and tianon committed Aug 7, 2021
1 parent ac449d6 commit 68e96f8
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 7 deletions.
2 changes: 1 addition & 1 deletion cmd/dockerd/config_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func installConfigFlags(conf *config.Config, flags *pflag.FlagSet) error {
flags.StringVar(&conf.InitPath, "init-path", "", "Path to the docker-init binary")
flags.Int64Var(&conf.CPURealtimePeriod, "cpu-rt-period", 0, "Limit the CPU real-time period in microseconds for the parent cgroup for all containers")
flags.Int64Var(&conf.CPURealtimeRuntime, "cpu-rt-runtime", 0, "Limit the CPU real-time runtime in microseconds for the parent cgroup for all containers")
flags.StringVar(&conf.SeccompProfile, "seccomp-profile", "", "Path to seccomp profile")
flags.StringVar(&conf.SeccompProfile, "seccomp-profile", config.SeccompProfileDefault, `Path to seccomp profile. Use "unconfined" to disable the default seccomp profile`)
flags.Var(&conf.ShmSize, "default-shm-size", "Default shm size for containers")
flags.BoolVar(&conf.NoNewPrivileges, "no-new-privileges", false, "Set no-new-privileges by default for new containers")
flags.StringVar(&conf.IpcMode, "default-ipc-mode", config.DefaultIpcMode, `Default mode for containers ipc ("shareable" | "private")`)
Expand Down
10 changes: 6 additions & 4 deletions daemon/daemon_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -1708,11 +1708,13 @@ func maybeCreateCPURealTimeFile(configValue int64, file string, path string) err
func (daemon *Daemon) setupSeccompProfile() error {
if daemon.configStore.SeccompProfile != "" {
daemon.seccompProfilePath = daemon.configStore.SeccompProfile
b, err := ioutil.ReadFile(daemon.configStore.SeccompProfile)
if err != nil {
return fmt.Errorf("opening seccomp profile (%s) failed: %v", daemon.configStore.SeccompProfile, err)
if daemon.configStore.SeccompProfile != config.SeccompProfileUnconfined {
b, err := ioutil.ReadFile(daemon.configStore.SeccompProfile)
if err != nil {
return fmt.Errorf("opening seccomp profile (%s) failed: %v", daemon.configStore.SeccompProfile, err)
}
daemon.seccompProfile = b
}
daemon.seccompProfile = b
}
return nil
}
Expand Down
2 changes: 2 additions & 0 deletions daemon/seccomp_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ func WithSeccomp(daemon *Daemon, c *container.Container) coci.SpecOpts {
s.Linux.Seccomp, err = seccomp.LoadProfile(c.SeccompProfile, s)
case daemon.seccompProfile != nil:
s.Linux.Seccomp, err = seccomp.LoadProfile(string(daemon.seccompProfile), s)
case daemon.seccompProfilePath == dconfig.SeccompProfileUnconfined:
c.SeccompProfile = dconfig.SeccompProfileUnconfined
default:
s.Linux.Seccomp, err = seccomp.GetDefaultProfile(s)
}
Expand Down
47 changes: 45 additions & 2 deletions integration/daemon/daemon_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import (
"runtime"
"testing"

"github.com/docker/docker/daemon/config"
"github.com/docker/docker/testutil/daemon"
"gotest.tools/v3/assert"
"gotest.tools/v3/skip"

is "gotest.tools/v3/assert/cmp"
"gotest.tools/v3/skip"
)

func TestConfigDaemonLibtrustID(t *testing.T) {
Expand Down Expand Up @@ -99,3 +99,46 @@ func TestDaemonConfigValidation(t *testing.T) {
})
}
}

func TestConfigDaemonSeccompProfiles(t *testing.T) {
skip.If(t, runtime.GOOS != "linux")

d := daemon.New(t)
defer d.Stop(t)

tests := []struct {
doc string
profile string
expectedProfile string
}{
{
doc: "empty profile set",
profile: "",
expectedProfile: config.SeccompProfileDefault,
},
{
doc: "unconfined profile",
profile: config.SeccompProfileUnconfined,
expectedProfile: config.SeccompProfileUnconfined,
},
}

for _, tc := range tests {
tc := tc
t.Run(tc.doc, func(t *testing.T) {
d.Start(t, "--seccomp-profile="+tc.profile)
info := d.Info(t)
assert.Assert(t, is.Contains(info.SecurityOptions, "name=seccomp,profile="+tc.expectedProfile))
d.Stop(t)

cfg := filepath.Join(d.RootDir(), "daemon.json")
err := ioutil.WriteFile(cfg, []byte(`{"seccomp-profile": "`+tc.profile+`"}`), 0644)
assert.NilError(t, err)

d.Start(t, "--config-file", cfg)
info = d.Info(t)
assert.Assert(t, is.Contains(info.SecurityOptions, "name=seccomp,profile="+tc.expectedProfile))
d.Stop(t)
})
}
}

0 comments on commit 68e96f8

Please sign in to comment.