From faa67dfff6368f69772f6bc949d5950cdff77328 Mon Sep 17 00:00:00 2001 From: Kir Kolyshkin Date: Tue, 22 Apr 2025 18:02:13 -0700 Subject: [PATCH] libct: maskPaths: don't rely on ENOTDIR for mount Currently, we rely on mount returning ENOTDIR when the destination is a directory (and so mount tells us that the source is not), and fall back to read-only tmpfs bind mount for such cases. Theoretically, ENOTDIR can also be returned in some other cases, resulting in the wrong type of mount being used. Let's be more straightforward here -- call fstat on destination file descriptor, and use the proper mount depending on whether it is a directory. Reported-by: Rodrigo Campos Signed-off-by: Kir Kolyshkin --- libcontainer/rootfs_linux.go | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go index f7f90356d..ed8ef7cd9 100644 --- a/libcontainer/rootfs_linux.go +++ b/libcontainer/rootfs_linux.go @@ -1294,19 +1294,25 @@ func maskPaths(paths []string, mountLabel string) error { } 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, "") + st, err := dstFh.Stat() + if err != nil { + dstFh.Close() + return fmt.Errorf("can't mask path %q: %w", path, err) + } + var dstType string + if st.IsDir() { + // Destination is a directory: bind mount a ro tmpfs over it. + dstType = "dir" + err = mount("tmpfs", path, "tmpfs", unix.MS_RDONLY, label.FormatMountLabel("", mountLabel)) + } else { + // Destination is a file: mount it to /dev/null. + dstType = "path" + 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) - } - // Destination is a directory: bind mount a ro tmpfs over it. - err := mount("tmpfs", path, "tmpfs", unix.MS_RDONLY, label.FormatMountLabel("", mountLabel)) - if err != nil { - return fmt.Errorf("can't mask dir %q: %w", path, err) - } + return fmt.Errorf("can't mask %s %q: %w", dstType, path, err) } }