MaskPaths: support directory
For example, the /sys/firmware directory should be masked because it can contain some sensitive files: - /sys/firmware/acpi/tables/{SLIC,MSDM}: Windows license information: - /sys/firmware/ibft/target0/chap-secret: iSCSI CHAP secret Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
This commit is contained in:
parent
e83ccf62aa
commit
53179559a1
|
@ -83,6 +83,7 @@ config := &configs.Config{
|
||||||
},
|
},
|
||||||
MaskPaths: []string{
|
MaskPaths: []string{
|
||||||
"/proc/kcore",
|
"/proc/kcore",
|
||||||
|
"/sys/firmware",
|
||||||
},
|
},
|
||||||
ReadonlyPaths: []string{
|
ReadonlyPaths: []string{
|
||||||
"/proc/sys", "/proc/sysrq-trigger", "/proc/irq", "/proc/bus",
|
"/proc/sys", "/proc/sysrq-trigger", "/proc/irq", "/proc/bus",
|
||||||
|
|
|
@ -56,6 +56,7 @@ func newTemplateConfig(rootfs string) *configs.Config {
|
||||||
},
|
},
|
||||||
MaskPaths: []string{
|
MaskPaths: []string{
|
||||||
"/proc/kcore",
|
"/proc/kcore",
|
||||||
|
"/sys/firmware",
|
||||||
},
|
},
|
||||||
ReadonlyPaths: []string{
|
ReadonlyPaths: []string{
|
||||||
"/proc/sys", "/proc/sysrq-trigger", "/proc/irq", "/proc/bus",
|
"/proc/sys", "/proc/sysrq-trigger", "/proc/irq", "/proc/bus",
|
||||||
|
|
|
@ -665,10 +665,16 @@ func remountReadonly(path string) error {
|
||||||
return fmt.Errorf("unable to mount %s as readonly max retries reached", path)
|
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
|
// maskPath masks the top of the specified path inside a container to avoid
|
||||||
// to avoid security issues from processes reading information from non-namespace aware mounts ( proc/kcore ).
|
// security issues from processes reading information from non-namespace aware
|
||||||
func maskFile(path string) error {
|
// 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.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 err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -108,7 +108,7 @@ func (l *linuxStandardInit) Init() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, path := range l.config.Config.MaskPaths {
|
for _, path := range l.config.Config.MaskPaths {
|
||||||
if err := maskFile(path); err != nil {
|
if err := maskPath(path); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1
spec.go
1
spec.go
|
@ -152,6 +152,7 @@ container on your host.`,
|
||||||
"/proc/timer_list",
|
"/proc/timer_list",
|
||||||
"/proc/timer_stats",
|
"/proc/timer_stats",
|
||||||
"/proc/sched_debug",
|
"/proc/sched_debug",
|
||||||
|
"/sys/firmware",
|
||||||
},
|
},
|
||||||
ReadonlyPaths: []string{
|
ReadonlyPaths: []string{
|
||||||
"/proc/asound",
|
"/proc/asound",
|
||||||
|
|
|
@ -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"* ]]
|
||||||
|
}
|
Loading…
Reference in New Issue