From 758d151e619042841b8a39cf4c0525b09d74887b Mon Sep 17 00:00:00 2001 From: Michael Crosby Date: Mon, 9 Feb 2015 15:38:28 -0800 Subject: [PATCH] Fully remove security package This moves the capabilities package into the root package. Signed-off-by: Michael Crosby --- linux_capabilities.go | 90 +++++++++++++++++++++++++++ linux_init.go | 9 ++- security/capabilities/capabilities.go | 56 ----------------- security/capabilities/types.go | 88 -------------------------- security/capabilities/types_test.go | 19 ------ 5 files changed, 96 insertions(+), 166 deletions(-) create mode 100644 linux_capabilities.go delete mode 100644 security/capabilities/capabilities.go delete mode 100644 security/capabilities/types.go delete mode 100644 security/capabilities/types_test.go diff --git a/linux_capabilities.go b/linux_capabilities.go new file mode 100644 index 00000000..b1c5c176 --- /dev/null +++ b/linux_capabilities.go @@ -0,0 +1,90 @@ +// +build linux + +package libcontainer + +import ( + "fmt" + "os" + + "github.com/syndtr/gocapability/capability" +) + +const allCapabilityTypes = capability.CAPS | capability.BOUNDS + +var capabilityList = map[string]capability.Cap{ + "SETPCAP": capability.CAP_SETPCAP, + "SYS_MODULE": capability.CAP_SYS_MODULE, + "SYS_RAWIO": capability.CAP_SYS_RAWIO, + "SYS_PACCT": capability.CAP_SYS_PACCT, + "SYS_ADMIN": capability.CAP_SYS_ADMIN, + "SYS_NICE": capability.CAP_SYS_NICE, + "SYS_RESOURCE": capability.CAP_SYS_RESOURCE, + "SYS_TIME": capability.CAP_SYS_TIME, + "SYS_TTY_CONFIG": capability.CAP_SYS_TTY_CONFIG, + "MKNOD": capability.CAP_MKNOD, + "AUDIT_WRITE": capability.CAP_AUDIT_WRITE, + "AUDIT_CONTROL": capability.CAP_AUDIT_CONTROL, + "MAC_OVERRIDE": capability.CAP_MAC_OVERRIDE, + "MAC_ADMIN": capability.CAP_MAC_ADMIN, + "NET_ADMIN": capability.CAP_NET_ADMIN, + "SYSLOG": capability.CAP_SYSLOG, + "CHOWN": capability.CAP_CHOWN, + "NET_RAW": capability.CAP_NET_RAW, + "DAC_OVERRIDE": capability.CAP_DAC_OVERRIDE, + "FOWNER": capability.CAP_FOWNER, + "DAC_READ_SEARCH": capability.CAP_DAC_READ_SEARCH, + "FSETID": capability.CAP_FSETID, + "KILL": capability.CAP_KILL, + "SETGID": capability.CAP_SETGID, + "SETUID": capability.CAP_SETUID, + "LINUX_IMMUTABLE": capability.CAP_LINUX_IMMUTABLE, + "NET_BIND_SERVICE": capability.CAP_NET_BIND_SERVICE, + "NET_BROADCAST": capability.CAP_NET_BROADCAST, + "IPC_LOCK": capability.CAP_IPC_LOCK, + "IPC_OWNER": capability.CAP_IPC_OWNER, + "SYS_CHROOT": capability.CAP_SYS_CHROOT, + "SYS_PTRACE": capability.CAP_SYS_PTRACE, + "SYS_BOOT": capability.CAP_SYS_BOOT, + "LEASE": capability.CAP_LEASE, + "SETFCAP": capability.CAP_SETFCAP, + "WAKE_ALARM": capability.CAP_WAKE_ALARM, + "BLOCK_SUSPEND": capability.CAP_BLOCK_SUSPEND, +} + +func newCapWhitelist(caps []string) (*whitelist, error) { + l := []capability.Cap{} + for _, c := range caps { + v, ok := capabilityList[c] + if !ok { + return nil, fmt.Errorf("unknown capability %q", c) + } + l = append(l, v) + } + pid, err := capability.NewPid(os.Getpid()) + if err != nil { + return nil, err + } + return &whitelist{ + keep: l, + pid: pid, + }, nil +} + +type whitelist struct { + pid capability.Capabilities + keep []capability.Cap +} + +// dropBoundingSet drops the capability bounding set to those specified in the whitelist. +func (w *whitelist) dropBoundingSet() error { + w.pid.Clear(capability.BOUNDS) + w.pid.Set(capability.BOUNDS, w.keep...) + return w.pid.Apply(capability.BOUNDS) +} + +// drop drops all capabilities for the current process except those specified in the whitelist. +func (w *whitelist) drop() error { + w.pid.Clear(allCapabilityTypes) + w.pid.Set(allCapabilityTypes, w.keep...) + return w.pid.Apply(allCapabilityTypes) +} diff --git a/linux_init.go b/linux_init.go index 663bfa6d..5ff1afc7 100644 --- a/linux_init.go +++ b/linux_init.go @@ -11,7 +11,6 @@ import ( "github.com/docker/libcontainer/configs" "github.com/docker/libcontainer/netlink" - "github.com/docker/libcontainer/security/capabilities" "github.com/docker/libcontainer/system" "github.com/docker/libcontainer/user" "github.com/docker/libcontainer/utils" @@ -97,8 +96,12 @@ func finalizeNamespace(config *initConfig) error { if err := utils.CloseExecFrom(3); err != nil { return err } + w, err := newCapWhitelist(config.Config.Capabilities) + if err != nil { + return err + } // drop capabilities in bounding set before changing user - if err := capabilities.DropBoundingSet(config.Config.Capabilities); err != nil { + if err := w.dropBoundingSet(); err != nil { return err } // preserve existing capabilities while we change users @@ -112,7 +115,7 @@ func finalizeNamespace(config *initConfig) error { return err } // drop all other capabilities - if err := capabilities.DropCapabilities(config.Config.Capabilities); err != nil { + if err := w.drop(); err != nil { return err } if config.Cwd != "" { diff --git a/security/capabilities/capabilities.go b/security/capabilities/capabilities.go deleted file mode 100644 index 7aef5fa6..00000000 --- a/security/capabilities/capabilities.go +++ /dev/null @@ -1,56 +0,0 @@ -package capabilities - -import ( - "os" - - "github.com/syndtr/gocapability/capability" -) - -const allCapabilityTypes = capability.CAPS | capability.BOUNDS - -// DropBoundingSet drops the capability bounding set to those specified in the -// container configuration. -func DropBoundingSet(capabilities []string) error { - c, err := capability.NewPid(os.Getpid()) - if err != nil { - return err - } - - keep := getEnabledCapabilities(capabilities) - c.Clear(capability.BOUNDS) - c.Set(capability.BOUNDS, keep...) - - if err := c.Apply(capability.BOUNDS); err != nil { - return err - } - - return nil -} - -// DropCapabilities drops all capabilities for the current process except those specified in the container configuration. -func DropCapabilities(capList []string) error { - c, err := capability.NewPid(os.Getpid()) - if err != nil { - return err - } - - keep := getEnabledCapabilities(capList) - c.Clear(allCapabilityTypes) - c.Set(allCapabilityTypes, keep...) - - if err := c.Apply(allCapabilityTypes); err != nil { - return err - } - return nil -} - -// getEnabledCapabilities returns the capabilities that should not be dropped by the container. -func getEnabledCapabilities(capList []string) []capability.Cap { - keep := []capability.Cap{} - for _, capability := range capList { - if c := GetCapability(capability); c != nil { - keep = append(keep, c.Value) - } - } - return keep -} diff --git a/security/capabilities/types.go b/security/capabilities/types.go deleted file mode 100644 index a960b804..00000000 --- a/security/capabilities/types.go +++ /dev/null @@ -1,88 +0,0 @@ -package capabilities - -import "github.com/syndtr/gocapability/capability" - -type ( - CapabilityMapping struct { - Key string `json:"key,omitempty"` - Value capability.Cap `json:"value,omitempty"` - } - Capabilities []*CapabilityMapping -) - -func (c *CapabilityMapping) String() string { - return c.Key -} - -func GetCapability(key string) *CapabilityMapping { - for _, capp := range capabilityList { - if capp.Key == key { - cpy := *capp - return &cpy - } - } - return nil -} - -func GetAllCapabilities() []string { - output := make([]string, len(capabilityList)) - for i, capability := range capabilityList { - output[i] = capability.String() - } - return output -} - -// Contains returns true if the specified Capability is -// in the slice -func (c Capabilities) contains(capp string) bool { - return c.get(capp) != nil -} - -func (c Capabilities) get(capp string) *CapabilityMapping { - for _, cap := range c { - if cap.Key == capp { - return cap - } - } - return nil -} - -var capabilityList = Capabilities{ - {Key: "SETPCAP", Value: capability.CAP_SETPCAP}, - {Key: "SYS_MODULE", Value: capability.CAP_SYS_MODULE}, - {Key: "SYS_RAWIO", Value: capability.CAP_SYS_RAWIO}, - {Key: "SYS_PACCT", Value: capability.CAP_SYS_PACCT}, - {Key: "SYS_ADMIN", Value: capability.CAP_SYS_ADMIN}, - {Key: "SYS_NICE", Value: capability.CAP_SYS_NICE}, - {Key: "SYS_RESOURCE", Value: capability.CAP_SYS_RESOURCE}, - {Key: "SYS_TIME", Value: capability.CAP_SYS_TIME}, - {Key: "SYS_TTY_CONFIG", Value: capability.CAP_SYS_TTY_CONFIG}, - {Key: "MKNOD", Value: capability.CAP_MKNOD}, - {Key: "AUDIT_WRITE", Value: capability.CAP_AUDIT_WRITE}, - {Key: "AUDIT_CONTROL", Value: capability.CAP_AUDIT_CONTROL}, - {Key: "MAC_OVERRIDE", Value: capability.CAP_MAC_OVERRIDE}, - {Key: "MAC_ADMIN", Value: capability.CAP_MAC_ADMIN}, - {Key: "NET_ADMIN", Value: capability.CAP_NET_ADMIN}, - {Key: "SYSLOG", Value: capability.CAP_SYSLOG}, - {Key: "CHOWN", Value: capability.CAP_CHOWN}, - {Key: "NET_RAW", Value: capability.CAP_NET_RAW}, - {Key: "DAC_OVERRIDE", Value: capability.CAP_DAC_OVERRIDE}, - {Key: "FOWNER", Value: capability.CAP_FOWNER}, - {Key: "DAC_READ_SEARCH", Value: capability.CAP_DAC_READ_SEARCH}, - {Key: "FSETID", Value: capability.CAP_FSETID}, - {Key: "KILL", Value: capability.CAP_KILL}, - {Key: "SETGID", Value: capability.CAP_SETGID}, - {Key: "SETUID", Value: capability.CAP_SETUID}, - {Key: "LINUX_IMMUTABLE", Value: capability.CAP_LINUX_IMMUTABLE}, - {Key: "NET_BIND_SERVICE", Value: capability.CAP_NET_BIND_SERVICE}, - {Key: "NET_BROADCAST", Value: capability.CAP_NET_BROADCAST}, - {Key: "IPC_LOCK", Value: capability.CAP_IPC_LOCK}, - {Key: "IPC_OWNER", Value: capability.CAP_IPC_OWNER}, - {Key: "SYS_CHROOT", Value: capability.CAP_SYS_CHROOT}, - {Key: "SYS_PTRACE", Value: capability.CAP_SYS_PTRACE}, - {Key: "SYS_BOOT", Value: capability.CAP_SYS_BOOT}, - {Key: "LEASE", Value: capability.CAP_LEASE}, - {Key: "SETFCAP", Value: capability.CAP_SETFCAP}, - {Key: "WAKE_ALARM", Value: capability.CAP_WAKE_ALARM}, - {Key: "BLOCK_SUSPEND", Value: capability.CAP_BLOCK_SUSPEND}, -} diff --git a/security/capabilities/types_test.go b/security/capabilities/types_test.go deleted file mode 100644 index 06e8a2b0..00000000 --- a/security/capabilities/types_test.go +++ /dev/null @@ -1,19 +0,0 @@ -package capabilities - -import ( - "testing" -) - -func TestCapabilitiesContains(t *testing.T) { - caps := Capabilities{ - GetCapability("MKNOD"), - GetCapability("SETPCAP"), - } - - if caps.contains("SYS_ADMIN") { - t.Fatal("capabilities should not contain SYS_ADMIN") - } - if !caps.contains("MKNOD") { - t.Fatal("capabilities should contain MKNOD but does not") - } -}