mirror of
https://github.com/opencontainers/runc.git
synced 2026-06-24 08:48:44 +00:00
Merge pull request #5285 from lifubang/followup-5275-maskpath
libct: Clean up and refactor maskPaths logic
This commit is contained in:
@@ -419,7 +419,7 @@ func mountCgroupV2(m mountEntry, c *mountConfig) error {
|
||||
// Mask `/sys/fs/cgroup` to ensure it is read-only, even when `/sys` is mounted
|
||||
// with `rbind,ro` (`runc spec --rootless` produces `rbind,ro` for `/sys`).
|
||||
err = utils.WithProcfdFile(m.dstFile, func(procfd string) error {
|
||||
return maskPaths(c.root, []string{procfd}, c.label)
|
||||
return maskDir(procfd, c.label)
|
||||
})
|
||||
}
|
||||
return err
|
||||
@@ -1328,12 +1328,20 @@ func verifyDevNull(f *os.File) error {
|
||||
})
|
||||
}
|
||||
|
||||
// maskDir mounts a read-only tmpfs on top of the specified path.
|
||||
func maskDir(path, mountLabel string) error {
|
||||
return mount("tmpfs", path, "tmpfs", unix.MS_RDONLY, label.FormatMountLabel("nr_blocks=1,nr_inodes=1", mountLabel))
|
||||
}
|
||||
|
||||
// maskPaths masks the top of the specified paths 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 maskPaths(rootFd *os.File, paths []string, mountLabel string) error {
|
||||
func maskPaths(rootFs string, paths []string, mountLabel string) error {
|
||||
if len(paths) == 0 {
|
||||
return nil
|
||||
}
|
||||
devNull, err := os.OpenFile("/dev/null", unix.O_PATH, 0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't mask paths: %w", err)
|
||||
@@ -1394,13 +1402,18 @@ func maskPaths(rootFd *os.File, paths []string, mountLabel string) error {
|
||||
}
|
||||
}
|
||||
if bindFailed || sharedMaskSrc == nil {
|
||||
err = mount("tmpfs", path, "tmpfs", unix.MS_RDONLY, label.FormatMountLabel("nr_blocks=1,nr_inodes=1", mountLabel))
|
||||
err = maskDir(path, mountLabel)
|
||||
if err == nil && !bindFailed && sharedMaskSrc == nil {
|
||||
// Establish this mount as the reusable shared source. reopenAfterMount
|
||||
// resolves the underlying inode via procfs and re-opens it through
|
||||
// rootFd, so the resulting fd is anchored to the real path inside the
|
||||
// container rootfs even if path was a /proc/self/fd/N alias.
|
||||
rootFd, err := os.OpenFile(rootFs, unix.O_DIRECTORY|unix.O_CLOEXEC|unix.O_PATH, 0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("open rootfs handle for masked paths: %w", err)
|
||||
}
|
||||
reopened, err := reopenAfterMount(rootFd, dstFh, unix.O_PATH|unix.O_CLOEXEC)
|
||||
rootFd.Close()
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't reopen shared directory mask: %w", err)
|
||||
}
|
||||
|
||||
@@ -142,17 +142,10 @@ func (l *linuxStandardInit) Init() error {
|
||||
}
|
||||
}
|
||||
|
||||
if len(l.config.Config.MaskPaths) > 0 {
|
||||
rootFd, err := os.OpenFile("/", unix.O_DIRECTORY|unix.O_CLOEXEC|unix.O_PATH, 0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("open rootfs handle for masked paths: %w", err)
|
||||
}
|
||||
err = maskPaths(rootFd, l.config.Config.MaskPaths, l.config.Config.MountLabel)
|
||||
rootFd.Close()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := maskPaths("/", l.config.Config.MaskPaths, l.config.Config.MountLabel); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
pdeath, err := system.GetParentDeathSignal()
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't get pdeath signal: %w", err)
|
||||
|
||||
Reference in New Issue
Block a user