mirror of
https://github.com/opencontainers/runc.git
synced 2025-10-05 15:37:02 +08:00
rootfs: umount all procfs and sysfs with --no-pivot
When creating a new user namespace, the kernel doesn't allow to mount a new procfs or sysfs file system if there is not already one instance fully visible in the current mount namespace. When using --no-pivot we were effectively inhibiting this protection from the kernel, as /proc and /sys from the host are still present in the container mount namespace. A container without full access to /proc could then create a new user namespace, and from there able to mount a fully visible /proc, bypassing the limitations in the container. A simple reproducer for this issue is: unshare -mrfp sh -c "mount -t proc none /proc && echo c > /proc/sysrq-trigger" Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
@@ -748,6 +748,41 @@ func pivotRoot(rootfs string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func msMoveRoot(rootfs string) error {
|
func msMoveRoot(rootfs string) error {
|
||||||
|
mountinfos, err := mount.GetMounts()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
absRootfs, err := filepath.Abs(rootfs)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, info := range mountinfos {
|
||||||
|
p, err := filepath.Abs(info.Mountpoint)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// Umount every syfs and proc file systems, except those under the container rootfs
|
||||||
|
if (info.Fstype != "proc" && info.Fstype != "sysfs") || filepath.HasPrefix(p, absRootfs) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
// Be sure umount events are not propagated to the host.
|
||||||
|
if err := unix.Mount("", p, "", unix.MS_SLAVE|unix.MS_REC, ""); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := unix.Unmount(p, unix.MNT_DETACH); err != nil {
|
||||||
|
if err != unix.EINVAL && err != unix.EPERM {
|
||||||
|
return err
|
||||||
|
} else {
|
||||||
|
// If we have not privileges for umounting (e.g. rootless), then
|
||||||
|
// cover the path.
|
||||||
|
if err := unix.Mount("tmpfs", p, "tmpfs", 0, ""); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if err := unix.Mount(rootfs, "/", "", unix.MS_MOVE, ""); err != nil {
|
if err := unix.Mount(rootfs, "/", "", unix.MS_MOVE, ""); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user