From 1a30a8f3d921acbbb6a4bb7e99da2c05f8d48522 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Mon, 21 Apr 2025 15:33:52 -0700 Subject: [PATCH] libct: maskPaths: only ignore ENOENT on mount dest When mounting a path being masked, the /dev/null might disappear from under us, and mount (even on an opened /dev/null file descriptor) will return ENOENT, which we deliberately ignore, as there's no need to mask non-existent paths. Let's open the destination path and ignore ENOENT during open, then mount via the destination file descriptor, not ignoring ENOENT. Reported-by: lifubang Signed-off-by: Kir Kolyshkin --- libcontainer/rootfs_linux.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go index 552734f56..04b568f48 100644 --- a/libcontainer/rootfs_linux.go +++ b/libcontainer/rootfs_linux.go @@ -1280,9 +1280,23 @@ func maskPaths(paths []string, mountLabel string) error { return fmt.Errorf("can't mask paths: %w", err) } devNullSrc := &mountSource{Type: mountSourcePlain, file: devNull} + procSelfFd, closer := utils.ProcThreadSelf("fd/") + defer closer() for _, path := range paths { - if err := mountViaFds("", devNullSrc, path, "", "", unix.MS_BIND, ""); err != nil && !errors.Is(err, os.ErrNotExist) { + // Open the target path; skip if it doesn't exist. + dstFh, err := os.OpenFile(path, unix.O_PATH|unix.O_CLOEXEC, 0) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + continue + } + return fmt.Errorf("can't mask path %q: %w", path, err) + } + + dstFd := filepath.Join(procSelfFd, strconv.Itoa(int(dstFh.Fd()))) + err = mountViaFds("", devNullSrc, path, dstFd, "", unix.MS_BIND, "") + dstFh.Close() + if err != nil { if !errors.Is(err, unix.ENOTDIR) { return fmt.Errorf("can't mask path %q: %w", path, err) }