diff --git a/libcontainer/README.md b/libcontainer/README.md index 457b132e..313b35c1 100644 --- a/libcontainer/README.md +++ b/libcontainer/README.md @@ -83,6 +83,7 @@ config := &configs.Config{ }, MaskPaths: []string{ "/proc/kcore", + "/sys/firmware", }, ReadonlyPaths: []string{ "/proc/sys", "/proc/sysrq-trigger", "/proc/irq", "/proc/bus", diff --git a/libcontainer/integration/template_test.go b/libcontainer/integration/template_test.go index 774032f5..a116ae30 100644 --- a/libcontainer/integration/template_test.go +++ b/libcontainer/integration/template_test.go @@ -56,6 +56,7 @@ func newTemplateConfig(rootfs string) *configs.Config { }, MaskPaths: []string{ "/proc/kcore", + "/sys/firmware", }, ReadonlyPaths: []string{ "/proc/sys", "/proc/sysrq-trigger", "/proc/irq", "/proc/bus", diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go index 67b7a275..aeb43885 100644 --- a/libcontainer/rootfs_linux.go +++ b/libcontainer/rootfs_linux.go @@ -665,10 +665,16 @@ func remountReadonly(path string) error { return fmt.Errorf("unable to mount %s as readonly max retries reached", path) } -// maskFile bind mounts /dev/null over the top of the specified path inside a container -// to avoid security issues from processes reading information from non-namespace aware mounts ( proc/kcore ). -func maskFile(path string) error { +// maskPath masks the top of the specified path inside a container to avoid +// security issues from processes reading information from non-namespace aware +// mounts ( proc/kcore ). +// For files, maskPath bind mounts /dev/null over the top of the specified path. +// For directories, maskPath mounts read-only tmpfs over the top of the specified path. +func maskPath(path string) error { if err := syscall.Mount("/dev/null", path, "", syscall.MS_BIND, ""); err != nil && !os.IsNotExist(err) { + if err == syscall.ENOTDIR { + return syscall.Mount("tmpfs", path, "tmpfs", syscall.MS_RDONLY, "") + } return err } return nil diff --git a/libcontainer/standard_init_linux.go b/libcontainer/standard_init_linux.go index 87515e1e..2104f1ad 100644 --- a/libcontainer/standard_init_linux.go +++ b/libcontainer/standard_init_linux.go @@ -108,7 +108,7 @@ func (l *linuxStandardInit) Init() error { } } for _, path := range l.config.Config.MaskPaths { - if err := maskFile(path); err != nil { + if err := maskPath(path); err != nil { return err } } diff --git a/spec.go b/spec.go index d3b3ab90..7834aa2a 100644 --- a/spec.go +++ b/spec.go @@ -152,6 +152,7 @@ container on your host.`, "/proc/timer_list", "/proc/timer_stats", "/proc/sched_debug", + "/sys/firmware", }, ReadonlyPaths: []string{ "/proc/asound", diff --git a/tests/integration/mask.bats b/tests/integration/mask.bats new file mode 100644 index 00000000..e10f8e5f --- /dev/null +++ b/tests/integration/mask.bats @@ -0,0 +1,56 @@ +#!/usr/bin/env bats + +load helpers + +function setup() { + teardown_busybox + setup_busybox +} + +function teardown() { + teardown_busybox +} + +@test "MaskPaths(file)" { + # run busybox detached + runc run -d --console /dev/pts/ptmx test_busybox + [ "$status" -eq 0 ] + + wait_for_container 15 1 test_busybox + + runc exec test_busybox cat /proc/kcore + [ "$status" -eq 0 ] + [[ "${output}" == "" ]] + + runc exec test_busybox rm -f /proc/kcore + [ "$status" -eq 1 ] + [[ "${output}" == *"Permission denied"* ]] + + runc exec test_busybox umount /proc/kcore + [ "$status" -eq 1 ] + [[ "${output}" == *"Operation not permitted"* ]] +} + +@test "MaskPaths(directory)" { + # run busybox detached + runc run -d --console /dev/pts/ptmx test_busybox + [ "$status" -eq 0 ] + + wait_for_container 15 1 test_busybox + + runc exec test_busybox ls /sys/firmware + [ "$status" -eq 0 ] + [[ "${output}" == "" ]] + + runc exec test_busybox touch /sys/firmware/foo + [ "$status" -eq 1 ] + [[ "${output}" == *"Read-only file system"* ]] + + runc exec test_busybox rm -rf /sys/firmware + [ "$status" -eq 1 ] + [[ "${output}" == *"Read-only file system"* ]] + + runc exec test_busybox umount /sys/firmware + [ "$status" -eq 1 ] + [[ "${output}" == *"Operation not permitted"* ]] +}