mirror of
				https://github.com/opencontainers/runc.git
				synced 2025-11-01 03:22:38 +08:00 
			
		
		
		
	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:
		
							
								
								
									
										90
									
								
								linux_capabilities.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								linux_capabilities.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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") |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
		Reference in New Issue
	
	Block a user
	 Michael Crosby
					Michael Crosby