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 <lifubang@acmcoder.com>
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
This commit is contained in:
Kir Kolyshkin
2025-04-21 15:33:52 -07:00
committed by Aleksa Sarai
parent 8476df83b5
commit 1a30a8f3d9

View File

@@ -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)
}