From b28eb9299e6ed9422c3b41f9493eb6469f41cf44 Mon Sep 17 00:00:00 2001 From: MohammadHasan Akbari Date: Fri, 13 Sep 2024 18:42:37 +0000 Subject: [PATCH] chore: return error when AppArmor is unsupported and profile is specifie Signed-off-by: MohammadHasan Akbari --- daemon/create.go | 27 +++++++++++++++++++++++++++ daemon/exec_linux.go | 7 +++++++ daemon/exec_linux_test.go | 1 + daemon/oci_linux.go | 6 ++++++ 4 files changed, 41 insertions(+) diff --git a/daemon/create.go b/daemon/create.go index 3e2227f743..4e05cc5ba4 100644 --- a/daemon/create.go +++ b/daemon/create.go @@ -7,6 +7,7 @@ import ( "strings" "time" + "github.com/containerd/containerd/pkg/apparmor" "github.com/containerd/log" "github.com/containerd/platforms" "github.com/docker/docker/api/types/backend" @@ -66,6 +67,32 @@ func (daemon *Daemon) containerCreate(ctx context.Context, daemonCfg *configStor return containertypes.CreateResponse{}, errdefs.InvalidParameter(fmt.Errorf("the logentries logging driver has been deprecated and removed")) } + var apparmorProfile string + for _, opt := range opts.params.HostConfig.SecurityOpt { + if strings.HasPrefix(opt, "apparmor") { + var value string + var ok bool + + if strings.Contains(opt, "=") { + _, value, ok = strings.Cut(opt, "=") + } else if strings.Contains(opt, ":") { + _, value, ok = strings.Cut(opt, ":") + } + + if !ok { + return containertypes.CreateResponse{}, fmt.Errorf("invalid apparmor security option: %s", opt) + } + + apparmorProfile = value + + break + } + } + + if apparmorProfile != "" && !apparmor.HostSupports() { + return containertypes.CreateResponse{}, fmt.Errorf("AppArmor is not supported on this host, but the profile %s was specified", apparmorProfile) + } + // Normalize some defaults. Doing this "ad-hoc" here for now, as there's // only one field to migrate, but we should consider having a better // location for this (and decide where in the flow would be most appropriate). diff --git a/daemon/exec_linux.go b/daemon/exec_linux.go index 3ab7492b22..f019692d40 100644 --- a/daemon/exec_linux.go +++ b/daemon/exec_linux.go @@ -2,6 +2,7 @@ package daemon // import "github.com/docker/docker/daemon" import ( "context" + "errors" "github.com/containerd/containerd" coci "github.com/containerd/containerd/oci" @@ -90,7 +91,13 @@ func (daemon *Daemon) execSetPlatformOpt(ctx context.Context, daemonCfg *config. } } p.ApparmorProfile = appArmorProfile + } else { + // If AppArmor is not supported but a profile was specified, return an error + if ec.Container.AppArmorProfile != "" { + return errors.New("AppArmor is not supported on this host, but the profile '" + ec.Container.AppArmorProfile + "' was specified") + } } + s := &specs.Spec{Process: p} return withRlimits(daemon, daemonCfg, ec.Container)(ctx, nil, nil, s) } diff --git a/daemon/exec_linux_test.go b/daemon/exec_linux_test.go index 0207c3df4f..7ce039889e 100644 --- a/daemon/exec_linux_test.go +++ b/daemon/exec_linux_test.go @@ -67,6 +67,7 @@ func TestExecSetPlatformOptAppArmor(t *testing.T) { if !appArmorEnabled { // no profile should be set if the host does not support AppArmor doc += " (apparmor disabled)" + tc.appArmorProfile = "" tc.expectedProfile = "" } if execPrivileged { diff --git a/daemon/oci_linux.go b/daemon/oci_linux.go index 2a8ca1be6f..d32833d4ab 100644 --- a/daemon/oci_linux.go +++ b/daemon/oci_linux.go @@ -179,7 +179,13 @@ func WithApparmor(c *container.Container) coci.SpecOpts { s.Process = &specs.Process{} } s.Process.ApparmorProfile = appArmorProfile + } else { + // If AppArmor is not supported but a profile was specified, return an error + if c.AppArmorProfile != "" { + return errors.New("AppArmor is not supported on this host, but the profile '" + c.AppArmorProfile + "' was specified") + } } + return nil } }