Fully remove security package
This moves the capabilities package into the root package. Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
ad49d71504
commit
758d151e61
|
@ -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)
|
||||||
|
}
|
|
@ -11,7 +11,6 @@ import (
|
||||||
|
|
||||||
"github.com/docker/libcontainer/configs"
|
"github.com/docker/libcontainer/configs"
|
||||||
"github.com/docker/libcontainer/netlink"
|
"github.com/docker/libcontainer/netlink"
|
||||||
"github.com/docker/libcontainer/security/capabilities"
|
|
||||||
"github.com/docker/libcontainer/system"
|
"github.com/docker/libcontainer/system"
|
||||||
"github.com/docker/libcontainer/user"
|
"github.com/docker/libcontainer/user"
|
||||||
"github.com/docker/libcontainer/utils"
|
"github.com/docker/libcontainer/utils"
|
||||||
|
@ -97,8 +96,12 @@ func finalizeNamespace(config *initConfig) error {
|
||||||
if err := utils.CloseExecFrom(3); err != nil {
|
if err := utils.CloseExecFrom(3); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
w, err := newCapWhitelist(config.Config.Capabilities)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
// drop capabilities in bounding set before changing user
|
// 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
|
return err
|
||||||
}
|
}
|
||||||
// preserve existing capabilities while we change users
|
// preserve existing capabilities while we change users
|
||||||
|
@ -112,7 +115,7 @@ func finalizeNamespace(config *initConfig) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// drop all other capabilities
|
// drop all other capabilities
|
||||||
if err := capabilities.DropCapabilities(config.Config.Capabilities); err != nil {
|
if err := w.drop(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if config.Cwd != "" {
|
if config.Cwd != "" {
|
||||||
|
|
|
@ -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
|
|
||||||
}
|
|
|
@ -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},
|
|
||||||
}
|
|
|
@ -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")
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue