Skip to content
This repository has been archived by the owner on Dec 13, 2018. It is now read-only.

Commit

Permalink
Improve libcontainer namespace and cap format
Browse files Browse the repository at this point in the history
Docker-DCO-1.1-Signed-off-by: Michael Crosby <michael@crosbymichael.com> (github: crosbymichael)
  • Loading branch information
crosbymichael committed May 5, 2014
1 parent 60ba7d0 commit 6c1bf62
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 207 deletions.
4 changes: 2 additions & 2 deletions container.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ type Container struct {
WorkingDir string `json:"working_dir,omitempty"` // current working directory
Env []string `json:"environment,omitempty"` // environment to set
Tty bool `json:"tty,omitempty"` // setup a proper tty or not
Namespaces Namespaces `json:"namespaces,omitempty"` // namespaces to apply
CapabilitiesMask Capabilities `json:"capabilities_mask,omitempty"` // capabilities to drop
Namespaces map[string]bool `json:"namespaces,omitempty"` // namespaces to apply
CapabilitiesMask map[string]bool `json:"capabilities_mask,omitempty"` // capabilities to drop
Networks []*Network `json:"networks,omitempty"` // nil for host's network stack
Cgroups *cgroups.Cgroup `json:"cgroups,omitempty"` // cgroups
Context Context `json:"context,omitempty"` // generic context for specific options (apparmor, selinux)
Expand Down
209 changes: 60 additions & 149 deletions container.json
Original file line number Diff line number Diff line change
@@ -1,151 +1,62 @@
{
"mounts" : [
{
"type" : "devtmpfs"
}
],
"tty" : true,
"environment" : [
"HOME=/",
"PATH=PATH=$PATH:/bin:/usr/bin:/sbin:/usr/sbin",
"container=docker",
"TERM=xterm-256color"
],
"hostname" : "koye",
"cgroups" : {
"parent" : "docker",
"name" : "docker-koye"
},
"capabilities_mask" : [
{
"value" : 8,
"key" : "SETPCAP",
"enabled" : false
},
{
"enabled" : false,
"value" : 16,
"key" : "SYS_MODULE"
},
{
"value" : 17,
"key" : "SYS_RAWIO",
"enabled" : false
},
{
"key" : "SYS_PACCT",
"value" : 20,
"enabled" : false
},
{
"value" : 21,
"key" : "SYS_ADMIN",
"enabled" : false
},
{
"value" : 23,
"key" : "SYS_NICE",
"enabled" : false
},
{
"value" : 24,
"key" : "SYS_RESOURCE",
"enabled" : false
},
{
"key" : "SYS_TIME",
"value" : 25,
"enabled" : false
},
{
"enabled" : false,
"value" : 26,
"key" : "SYS_TTY_CONFIG"
},
{
"key" : "AUDIT_WRITE",
"value" : 29,
"enabled" : false
},
{
"value" : 30,
"key" : "AUDIT_CONTROL",
"enabled" : false
},
{
"enabled" : false,
"key" : "MAC_OVERRIDE",
"value" : 32
},
{
"enabled" : false,
"key" : "MAC_ADMIN",
"value" : 33
},
{
"key" : "NET_ADMIN",
"value" : 12,
"enabled" : false
},
{
"value" : 27,
"key" : "MKNOD",
"enabled" : true
},
{
"value" : 34,
"key" : "SYSLOG",
"enabled" : false
}
],
"networks" : [
{
"mtu" : 1500,
"address" : "127.0.0.1/0",
"type" : "loopback",
"gateway" : "localhost"
},
{
"mtu" : 1500,
"address" : "172.17.42.2/16",
"type" : "veth",
"context" : {
"bridge" : "docker0",
"prefix" : "veth"
},
"gateway" : "172.17.42.1"
}
],
"namespaces" : [
{
"key" : "NEWNS",
"value" : 131072,
"enabled" : true,
"file" : "mnt"
},
{
"key" : "NEWUTS",
"value" : 67108864,
"enabled" : true,
"file" : "uts"
},
{
"enabled" : true,
"file" : "ipc",
"key" : "NEWIPC",
"value" : 134217728
},
{
"file" : "pid",
"enabled" : true,
"value" : 536870912,
"key" : "NEWPID"
},
{
"enabled" : true,
"file" : "net",
"key" : "NEWNET",
"value" : 1073741824
}
]
"namespaces": {
"NEWNET": true,
"NEWPID": true,
"NEWIPC": true,
"NEWUTS": true,
"NEWNS": true
},
"networks": [
{
"gateway": "localhost",
"type": "loopback",
"address": "127.0.0.1/0",
"mtu": 1500
},
{
"gateway": "172.17.42.1",
"context": {
"prefix": "veth",
"bridge": "docker0"
},
"type": "veth",
"address": "172.17.42.2/16",
"mtu": 1500
}
],
"capabilities_mask": {
"SYSLOG": false,
"MKNOD": true,
"NET_ADMIN": false,
"MAC_ADMIN": false,
"MAC_OVERRIDE": false,
"AUDIT_CONTROL": false,
"AUDIT_WRITE": false,
"SYS_TTY_CONFIG": false,
"SETPCAP": false,
"SYS_MODULE": false,
"SYS_RAWIO": false,
"SYS_PACCT": false,
"SYS_ADMIN": false,
"SYS_NICE": false,
"SYS_RESOURCE": false,
"SYS_TIME": false
},
"cgroups": {
"name": "docker-koye",
"parent": "docker"
},
"hostname": "koye",
"environment": [
"HOME=/",
"PATH=PATH=$PATH:/bin:/usr/bin:/sbin:/usr/sbin",
"container=docker",
"TERM=xterm-256color"
],
"tty": true,
"mounts": [
{
"type": "devtmpfs"
}
]
}
14 changes: 7 additions & 7 deletions container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ func TestContainerJsonFormat(t *testing.T) {

var container *Container
if err := json.NewDecoder(f).Decode(&container); err != nil {
t.Fatal("failed to decode container config")
t.Fatalf("failed to decode container config: %s", err)
}
if container.Hostname != "koye" {
t.Log("hostname is not set")
Expand All @@ -27,32 +27,32 @@ func TestContainerJsonFormat(t *testing.T) {
t.Fail()
}

if !container.Namespaces.Contains("NEWNET") {
if !container.Namespaces["NEWNET"] {
t.Log("namespaces should contain NEWNET")
t.Fail()
}

if container.Namespaces.Contains("NEWUSER") {
if container.Namespaces["NEWUSER"] {
t.Log("namespaces should not contain NEWUSER")
t.Fail()
}

if !container.CapabilitiesMask.Contains("SYS_ADMIN") {
if _, exists := container.CapabilitiesMask["SYS_ADMIN"]; !exists {
t.Log("capabilities mask should contain SYS_ADMIN")
t.Fail()
}

if container.CapabilitiesMask.Get("SYS_ADMIN").Enabled {
if container.CapabilitiesMask["SYS_ADMIN"] {
t.Log("SYS_ADMIN should not be enabled in capabilities mask")
t.Fail()
}

if !container.CapabilitiesMask.Get("MKNOD").Enabled {
if !container.CapabilitiesMask["MKNOD"] {
t.Log("MKNOD should be enabled in capabilities mask")
t.Fail()
}

if container.CapabilitiesMask.Contains("SYS_CHROOT") {
if container.CapabilitiesMask["SYS_CHROOT"] {
t.Log("capabilities mask should not contain SYS_CHROOT")
t.Fail()
}
Expand Down
10 changes: 6 additions & 4 deletions nsinit/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,12 @@ func InitializeNetworking(container *libcontainer.Container, nspid int, pipe *Sy

// GetNamespaceFlags parses the container's Namespaces options to set the correct
// flags on clone, unshare, and setns
func GetNamespaceFlags(namespaces libcontainer.Namespaces) (flag int) {
for _, ns := range namespaces {
if ns.Enabled {
flag |= ns.Value
func GetNamespaceFlags(namespaces map[string]bool) (flag int) {
for key, enabled := range namespaces {
if enabled {
if ns := libcontainer.GetNamespace(key); ns != nil {
flag |= ns.Value
}
}
}
return flag
Expand Down
29 changes: 18 additions & 11 deletions nsinit/execin.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,13 @@ func ExecIn(container *libcontainer.Container, nspid int, args []string) (int, e
return -1, err
}

for _, nsv := range container.Namespaces {
for key, enabled := range container.Namespaces {
// skip the PID namespace on unshare because it it not supported
if nsv.Enabled && nsv.Key != "NEWPID" {
if err := system.Unshare(nsv.Value); err != nil {
return -1, err
if enabled && key != "NEWPID" {
if ns := libcontainer.GetNamespace(key); ns != nil {
if err := system.Unshare(ns.Value); err != nil {
return -1, err
}
}
}
}
Expand Down Expand Up @@ -59,7 +61,7 @@ func ExecIn(container *libcontainer.Container, nspid int, args []string) (int, e

// if the container has a new pid and mount namespace we need to
// remount proc and sys to pick up the changes
if container.Namespaces.Contains("NEWNS") && container.Namespaces.Contains("NEWPID") {
if container.Namespaces["NEWNS"] && container.Namespaces["NEWPID"] {
pid, err := system.Fork()
if err != nil {
return -1, err
Expand Down Expand Up @@ -102,13 +104,18 @@ dropAndExec:
}

func getNsFds(pid int, container *libcontainer.Container) ([]uintptr, error) {
fds := make([]uintptr, len(container.Namespaces))
for i, ns := range container.Namespaces {
f, err := os.OpenFile(filepath.Join("/proc/", strconv.Itoa(pid), "ns", ns.File), os.O_RDONLY, 0)
if err != nil {
return fds, err
fds := []uintptr{}

for key, enabled := range container.Namespaces {
if enabled {
if ns := libcontainer.GetNamespace(key); ns != nil {
f, err := os.OpenFile(filepath.Join("/proc/", strconv.Itoa(pid), "ns", ns.File), os.O_RDONLY, 0)
if err != nil {
return fds, err
}
fds = append(fds, f.Fd())
}
}
fds[i] = f.Fd()
}
return fds, nil
}
2 changes: 1 addition & 1 deletion nsinit/unsupported.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ func SetupCgroups(container *libcontainer.Container, nspid int) (cgroups.ActiveC
return nil, libcontainer.ErrUnsupported
}

func GetNamespaceFlags(namespaces libcontainer.Namespaces) (flag int) {
func GetNamespaceFlags(namespaces map[string]bool) (flag int) {
return 0
}
11 changes: 7 additions & 4 deletions security/capabilities/capabilities.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package capabilities

import (
"os"

"github.com/dotcloud/docker/pkg/libcontainer"
"github.com/syndtr/gocapability/capability"
"os"
)

// DropCapabilities drops capabilities for the current process based
Expand All @@ -26,9 +27,11 @@ func DropCapabilities(container *libcontainer.Container) error {
// getCapabilitiesMask returns the specific cap mask values for the libcontainer types
func getCapabilitiesMask(container *libcontainer.Container) []capability.Cap {
drop := []capability.Cap{}
for _, c := range container.CapabilitiesMask {
if !c.Enabled {
drop = append(drop, c.Value)
for key, enabled := range container.CapabilitiesMask {
if !enabled {
if c := libcontainer.GetCapability(key); c != nil {
drop = append(drop, c.Value)
}
}
}
return drop
Expand Down
Loading

0 comments on commit 6c1bf62

Please sign in to comment.