mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
add check for invalid caps
Docker-DCO-1.1-Signed-off-by: Victor Vieux <vieux@docker.com> (github: vieux)
This commit is contained in:
parent
064b5f870d
commit
c04230c42b
4 changed files with 67 additions and 12 deletions
|
@ -49,7 +49,10 @@ func finalizeNamespace(args *execdriver.InitArgs) error {
|
||||||
return fmt.Errorf("clear keep caps %s", err)
|
return fmt.Errorf("clear keep caps %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
caps := execdriver.TweakCapabilities(container.Capabilities, strings.Split(args.CapAdd, " "), strings.Split(args.CapDrop, " "))
|
caps, err := execdriver.TweakCapabilities(container.Capabilities, strings.Split(args.CapAdd, " "), strings.Split(args.CapDrop, " "))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// drop all other capabilities
|
// drop all other capabilities
|
||||||
if err := capabilities.DropCapabilities(caps); err != nil {
|
if err := capabilities.DropCapabilities(caps); err != nil {
|
||||||
|
|
|
@ -43,7 +43,9 @@ func (d *driver) createContainer(c *execdriver.Command) (*libcontainer.Config, e
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
d.setCapabilities(container, c)
|
if err := d.setCapabilities(container, c); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := d.setupCgroups(container, c); err != nil {
|
if err := d.setupCgroups(container, c); err != nil {
|
||||||
|
@ -138,8 +140,9 @@ func (d *driver) setPrivileged(container *libcontainer.Config) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *driver) setCapabilities(container *libcontainer.Config, c *execdriver.Command) {
|
func (d *driver) setCapabilities(container *libcontainer.Config, c *execdriver.Command) (err error) {
|
||||||
container.Capabilities = execdriver.TweakCapabilities(container.Capabilities, c.CapAdd, c.CapDrop)
|
container.Capabilities, err = execdriver.TweakCapabilities(container.Capabilities, c.CapAdd, c.CapDrop)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *driver) setupCgroups(container *libcontainer.Config, c *execdriver.Command) error {
|
func (d *driver) setupCgroups(container *libcontainer.Config, c *execdriver.Command) error {
|
||||||
|
|
|
@ -1,34 +1,63 @@
|
||||||
package execdriver
|
package execdriver
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/libcontainer/security/capabilities"
|
"github.com/docker/libcontainer/security/capabilities"
|
||||||
"github.com/dotcloud/docker/utils"
|
"github.com/dotcloud/docker/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TweakCapabilities(basics, adds, drops []string) []string {
|
func TweakCapabilities(basics, adds, drops []string) ([]string, error) {
|
||||||
var caps []string
|
var (
|
||||||
|
newCaps []string
|
||||||
|
allCaps = capabilities.GetAllCapabilities()
|
||||||
|
)
|
||||||
|
|
||||||
|
// look for invalid cap in the drop list
|
||||||
|
for _, cap := range drops {
|
||||||
|
if strings.ToLower(cap) == "all" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !utils.StringsContainsNoCase(allCaps, cap) {
|
||||||
|
return nil, fmt.Errorf("Unknown capability: %s", cap)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle --cap-add=all
|
||||||
if utils.StringsContainsNoCase(adds, "all") {
|
if utils.StringsContainsNoCase(adds, "all") {
|
||||||
basics = capabilities.GetAllCapabilities()
|
basics = capabilities.GetAllCapabilities()
|
||||||
}
|
}
|
||||||
|
|
||||||
if !utils.StringsContainsNoCase(drops, "all") {
|
if !utils.StringsContainsNoCase(drops, "all") {
|
||||||
for _, cap := range basics {
|
for _, cap := range basics {
|
||||||
|
// skip `all` aready handled above
|
||||||
|
if strings.ToLower(cap) == "all" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we don't drop `all`, add back all the non-dropped caps
|
||||||
if !utils.StringsContainsNoCase(drops, cap) {
|
if !utils.StringsContainsNoCase(drops, cap) {
|
||||||
caps = append(caps, cap)
|
newCaps = append(newCaps, cap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, cap := range adds {
|
for _, cap := range adds {
|
||||||
|
// skip `all` aready handled above
|
||||||
if strings.ToLower(cap) == "all" {
|
if strings.ToLower(cap) == "all" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if !utils.StringsContainsNoCase(caps, cap) {
|
|
||||||
caps = append(caps, cap)
|
// look for invalid cap in the drop list
|
||||||
|
if !utils.StringsContainsNoCase(allCaps, cap) {
|
||||||
|
return nil, fmt.Errorf("Unknown capability: %s", cap)
|
||||||
|
}
|
||||||
|
|
||||||
|
// add cap if not already in the list
|
||||||
|
if !utils.StringsContainsNoCase(newCaps, cap) {
|
||||||
|
newCaps = append(newCaps, cap)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return caps
|
return newCaps, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -783,6 +783,16 @@ func TestUnPrivilegedCanMknod(t *testing.T) {
|
||||||
logDone("run - test un-privileged can mknod")
|
logDone("run - test un-privileged can mknod")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCapDropInvalid(t *testing.T) {
|
||||||
|
cmd := exec.Command(dockerBinary, "run", "--cap-drop=CHPASS", "busybox", "ls")
|
||||||
|
out, _, err := runCommandWithOutput(cmd)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal(err, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
logDone("run - test --cap-drop=CHPASS invalid")
|
||||||
|
}
|
||||||
|
|
||||||
func TestCapDropCannotMknod(t *testing.T) {
|
func TestCapDropCannotMknod(t *testing.T) {
|
||||||
cmd := exec.Command(dockerBinary, "run", "--cap-drop=MKNOD", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
|
cmd := exec.Command(dockerBinary, "run", "--cap-drop=MKNOD", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
|
||||||
out, _, err := runCommandWithOutput(cmd)
|
out, _, err := runCommandWithOutput(cmd)
|
||||||
|
@ -814,7 +824,7 @@ func TestCapDropALLCannotMknod(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCapDropALLAddMknodCannotMknod(t *testing.T) {
|
func TestCapDropALLAddMknodCannotMknod(t *testing.T) {
|
||||||
cmd := exec.Command(dockerBinary, "run", "--cap-drop=ALL --cap-add=MKNOD", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
|
cmd := exec.Command(dockerBinary, "run", "--cap-drop=ALL", "--cap-add=MKNOD", "busybox", "sh", "-c", "mknod /tmp/sda b 8 0 && echo ok")
|
||||||
out, _, err := runCommandWithOutput(cmd)
|
out, _, err := runCommandWithOutput(cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err, out)
|
t.Fatal(err, out)
|
||||||
|
@ -828,6 +838,16 @@ func TestCapDropALLAddMknodCannotMknod(t *testing.T) {
|
||||||
logDone("run - test --cap-drop=ALL --cap-add=MKNOD can mknod")
|
logDone("run - test --cap-drop=ALL --cap-add=MKNOD can mknod")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCapAddInvalid(t *testing.T) {
|
||||||
|
cmd := exec.Command(dockerBinary, "run", "--cap-add=CHPASS", "busybox", "ls")
|
||||||
|
out, _, err := runCommandWithOutput(cmd)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatal(err, out)
|
||||||
|
}
|
||||||
|
|
||||||
|
logDone("run - test --cap-add=CHPASS invalid")
|
||||||
|
}
|
||||||
|
|
||||||
func TestCapAddCanDownInterface(t *testing.T) {
|
func TestCapAddCanDownInterface(t *testing.T) {
|
||||||
cmd := exec.Command(dockerBinary, "run", "--cap-add=NET_ADMIN", "busybox", "sh", "-c", "ip link set eth0 down && echo ok")
|
cmd := exec.Command(dockerBinary, "run", "--cap-add=NET_ADMIN", "busybox", "sh", "-c", "ip link set eth0 down && echo ok")
|
||||||
out, _, err := runCommandWithOutput(cmd)
|
out, _, err := runCommandWithOutput(cmd)
|
||||||
|
@ -859,7 +879,7 @@ func TestCapAddALLCanDownInterface(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCapAddALLDropNetAdminCanDownInterface(t *testing.T) {
|
func TestCapAddALLDropNetAdminCanDownInterface(t *testing.T) {
|
||||||
cmd := exec.Command(dockerBinary, "run", "--cap-add=ALL --cap-drop=NET_ADMIN", "busybox", "sh", "-c", "ip link set eth0 down && echo ok")
|
cmd := exec.Command(dockerBinary, "run", "--cap-add=ALL", "--cap-drop=NET_ADMIN", "busybox", "sh", "-c", "ip link set eth0 down && echo ok")
|
||||||
out, _, err := runCommandWithOutput(cmd)
|
out, _, err := runCommandWithOutput(cmd)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal(err, out)
|
t.Fatal(err, out)
|
||||||
|
|
Loading…
Add table
Reference in a new issue