From abf70bab6344e1627850d038740245bd9e2787e4 Mon Sep 17 00:00:00 2001 From: lifubang Date: Tue, 12 May 2026 03:26:27 +0000 Subject: [PATCH] libct: skip mount for duplicate masked paths Co-authored-by: Davanum Srinivas Refactored-by: lifubang Signed-off-by: lifubang --- libcontainer/rootfs_linux.go | 9 +++++++++ tests/integration/mask.bats | 14 ++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/libcontainer/rootfs_linux.go b/libcontainer/rootfs_linux.go index ef764df5f..15fe0a8cd 100644 --- a/libcontainer/rootfs_linux.go +++ b/libcontainer/rootfs_linux.go @@ -1346,6 +1346,7 @@ func maskPaths(paths []string, mountLabel string) error { procSelfFd, closer := utils.ProcThreadSelf("fd/") defer closer() + maskedPaths := make(map[string]struct{}) for _, path := range paths { // Open the target path; skip if it doesn't exist. dstFh, err := os.OpenFile(path, unix.O_PATH|unix.O_CLOEXEC, 0) @@ -1360,6 +1361,14 @@ func maskPaths(paths []string, mountLabel string) error { dstFh.Close() return fmt.Errorf("can't mask path %q: %w", path, err) } + // skip duplicate masked paths. + cleanPath := pathrs.LexicallyCleanPath(path) + if _, ok := maskedPaths[cleanPath]; ok { + dstFh.Close() + continue + } + maskedPaths[cleanPath] = struct{}{} + var dstType string if st.IsDir() { // Destination is a directory: bind mount a ro tmpfs over it. diff --git a/tests/integration/mask.bats b/tests/integration/mask.bats index 5783332ea..6cc9339df 100644 --- a/tests/integration/mask.bats +++ b/tests/integration/mask.bats @@ -55,6 +55,20 @@ function teardown() { [[ "${output}" == *"Operation not permitted"* ]] } +@test "mask paths [duplicate paths]" { + update_config '(.. | select(.maskedPaths? != null)) .maskedPaths += ["/testdir", "/testfile"]' + runc run -d --console-socket "$CONSOLE_SOCKET" test_busybox + [ "$status" -eq 0 ] + + runc exec test_busybox sh -c "mount | grep /testdir -c" + [ "$status" -eq 0 ] + [[ "${output}" == "1" ]] + + runc exec test_busybox sh -c "mount | grep /testfile -c" + [ "$status" -eq 0 ] + [[ "${output}" == "1" ]] +} + @test "mask paths [prohibit symlink /proc]" { ln -s /symlink rootfs/proc runc run -d --console-socket "$CONSOLE_SOCKET" test_busybox