From d31ae5aed80eeb40a461930776ad2b507804bf4e Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Thu, 19 Jun 2014 11:07:57 -0700 Subject: [PATCH] Use libcontainer cap drop method Docker-DCO-1.1-Signed-off-by: Michael Crosby (github: crosbymichael) --- daemon/execdriver/lxc/driver.go | 9 +- daemon/execdriver/lxc/init.go | 123 ------------------ daemon/execdriver/lxc/lxc_init_linux.go | 42 ++++++ daemon/execdriver/lxc/lxc_init_unsupported.go | 6 + pkg/system/unsupported.go | 8 ++ 5 files changed, 64 insertions(+), 124 deletions(-) diff --git a/daemon/execdriver/lxc/driver.go b/daemon/execdriver/lxc/driver.go index 634ccbd143..24144dc194 100644 --- a/daemon/execdriver/lxc/driver.go +++ b/daemon/execdriver/lxc/driver.go @@ -19,6 +19,7 @@ import ( "github.com/docker/libcontainer/label" "github.com/docker/libcontainer/mount/nodes" "github.com/dotcloud/docker/daemon/execdriver" + "github.com/dotcloud/docker/pkg/system" "github.com/dotcloud/docker/utils" ) @@ -36,7 +37,13 @@ func init() { if err := setupNetworking(args); err != nil { return err } - if err := setupCapabilities(args); err != nil { + if err := setupWorkingDirectory(args); err != nil { + return err + } + if err := system.CloseFdsFrom(3); err != nil { + return err + } + if err := finalizeNamespace(args); err != nil { return err } diff --git a/daemon/execdriver/lxc/init.go b/daemon/execdriver/lxc/init.go index 2f871b5286..1af7730cae 100644 --- a/daemon/execdriver/lxc/init.go +++ b/daemon/execdriver/lxc/init.go @@ -11,9 +11,6 @@ import ( "github.com/docker/libcontainer/netlink" "github.com/dotcloud/docker/daemon/execdriver" - "github.com/dotcloud/docker/pkg/system" - "github.com/dotcloud/docker/pkg/user" - "github.com/syndtr/gocapability/capability" ) // Clear environment pollution introduced by lxc-start @@ -108,126 +105,6 @@ func setupWorkingDirectory(args *execdriver.InitArgs) error { return nil } -// Takes care of dropping privileges to the desired user -func changeUser(args *execdriver.InitArgs) error { - uid, gid, suppGids, err := user.GetUserGroupSupplementary( - args.User, - syscall.Getuid(), syscall.Getgid(), - ) - if err != nil { - return err - } - - if err := syscall.Setgroups(suppGids); err != nil { - return fmt.Errorf("Setgroups failed: %v", err) - } - if err := syscall.Setgid(gid); err != nil { - return fmt.Errorf("Setgid failed: %v", err) - } - if err := syscall.Setuid(uid); err != nil { - return fmt.Errorf("Setuid failed: %v", err) - } - - return nil -} - -var whiteList = []capability.Cap{ - capability.CAP_MKNOD, - capability.CAP_SETUID, - capability.CAP_SETGID, - capability.CAP_CHOWN, - capability.CAP_NET_RAW, - capability.CAP_DAC_OVERRIDE, - capability.CAP_FOWNER, - capability.CAP_FSETID, - capability.CAP_KILL, - capability.CAP_SETGID, - capability.CAP_SETUID, - capability.CAP_LINUX_IMMUTABLE, - capability.CAP_NET_BIND_SERVICE, - capability.CAP_NET_BROADCAST, - capability.CAP_IPC_LOCK, - capability.CAP_IPC_OWNER, - capability.CAP_SYS_CHROOT, - capability.CAP_SYS_PTRACE, - capability.CAP_SYS_BOOT, - capability.CAP_LEASE, - capability.CAP_SETFCAP, - capability.CAP_WAKE_ALARM, - capability.CAP_BLOCK_SUSPEND, -} - -func dropBoundingSet() error { - c, err := capability.NewPid(os.Getpid()) - if err != nil { - return err - } - c.Clear(capability.BOUNDS) - c.Set(capability.BOUNDS, whiteList...) - - if err := c.Apply(capability.BOUNDS); err != nil { - return err - } - - return nil -} - -const allCapabilityTypes = capability.CAPS | capability.BOUNDS - -func dropCapabilities() error { - c, err := capability.NewPid(os.Getpid()) - if err != nil { - return err - } - c.Clear(allCapabilityTypes) - c.Set(allCapabilityTypes, whiteList...) - - if err := c.Apply(allCapabilityTypes); err != nil { - return err - } - - return nil -} - -func setupCapabilities(args *execdriver.InitArgs) error { - if err := system.CloseFdsFrom(3); err != nil { - return err - } - - if !args.Privileged { - // drop capabilities in bounding set before changing user - if err := dropBoundingSet(); err != nil { - return fmt.Errorf("drop bounding set %s", err) - } - - // preserve existing capabilities while we change users - if err := system.SetKeepCaps(); err != nil { - return fmt.Errorf("set keep caps %s", err) - } - } - - if err := changeUser(args); err != nil { - return err - } - - if !args.Privileged { - if err := system.ClearKeepCaps(); err != nil { - return fmt.Errorf("clear keep caps %s", err) - } - - // drop all other capabilities - if err := dropCapabilities(); err != nil { - return fmt.Errorf("drop capabilities %s", err) - } - } - - if err := setupWorkingDirectory(args); err != nil { - return err - } - - return nil -} - func getEnv(args *execdriver.InitArgs, key string) string { for _, kv := range args.Env { parts := strings.SplitN(kv, "=", 2) diff --git a/daemon/execdriver/lxc/lxc_init_linux.go b/daemon/execdriver/lxc/lxc_init_linux.go index 7288f5877b..6069c4becc 100644 --- a/daemon/execdriver/lxc/lxc_init_linux.go +++ b/daemon/execdriver/lxc/lxc_init_linux.go @@ -3,9 +3,51 @@ package lxc import ( + "fmt" "syscall" + + "github.com/docker/libcontainer/namespaces" + "github.com/docker/libcontainer/security/capabilities" + "github.com/dotcloud/docker/daemon/execdriver" + "github.com/dotcloud/docker/daemon/execdriver/native/template" + "github.com/dotcloud/docker/pkg/system" ) func setHostname(hostname string) error { return syscall.Sethostname([]byte(hostname)) } + +func finalizeNamespace(args *execdriver.InitArgs) error { + // We use the native drivers default template so that things like caps are consistent + // across both drivers + container := template.New() + + if !args.Privileged { + // drop capabilities in bounding set before changing user + if err := capabilities.DropBoundingSet(container); err != nil { + return fmt.Errorf("drop bounding set %s", err) + } + + // preserve existing capabilities while we change users + if err := system.SetKeepCaps(); err != nil { + return fmt.Errorf("set keep caps %s", err) + } + } + + if err := namespaces.SetupUser(args.User); err != nil { + return fmt.Errorf("setup user %s", err) + } + + if !args.Privileged { + if err := system.ClearKeepCaps(); err != nil { + return fmt.Errorf("clear keep caps %s", err) + } + + // drop all other capabilities + if err := capabilities.DropCapabilities(container); err != nil { + return fmt.Errorf("drop capabilities %s", err) + } + } + + return nil +} diff --git a/daemon/execdriver/lxc/lxc_init_unsupported.go b/daemon/execdriver/lxc/lxc_init_unsupported.go index d68cb91a1e..079446e186 100644 --- a/daemon/execdriver/lxc/lxc_init_unsupported.go +++ b/daemon/execdriver/lxc/lxc_init_unsupported.go @@ -2,6 +2,12 @@ package lxc +import "github.com/dotcloud/docker/daemon/execdriver" + func setHostname(hostname string) error { panic("Not supported on darwin") } + +func finalizeNamespace(args *execdriver.InitArgs) error { + panic("Not supported on darwin") +} diff --git a/pkg/system/unsupported.go b/pkg/system/unsupported.go index 96ebc858f5..aea4b69f97 100644 --- a/pkg/system/unsupported.go +++ b/pkg/system/unsupported.go @@ -28,3 +28,11 @@ func GetClockTicks() int { func CreateMasterAndConsole() (*os.File, string, error) { return nil, "", ErrNotSupportedPlatform } + +func SetKeepCaps() error { + return ErrNotSupportedPlatform +} + +func ClearKeepCaps() error { + return ErrNotSupportedPlatform +}