From d684118a7c464c7fc117756e5c6518e45bbe66df Mon Sep 17 00:00:00 2001 From: PiliLily Date: Wed, 19 Aug 2026 22:50:36 +0800 Subject: [PATCH] selftests/tkernel: cover shield_mounts namespace visibility shield_mounts only filters procfs mount views for tasks in a non-root PID namespace. Existing tests cover parsing but do not exercise the host and container visibility contract. Create a dedicated tmpfs mount and register it with shield_mounts. Check that the root PID namespace still sees it in both mounts and mountinfo, while a child mount and PID namespace sees neither view. Clear the entry from that child and verify both views return and the host observes the global configuration change. Upstream status: downstream-only Signed-off-by: PiliLily --- .../selftests/tkernel/shield_mounts.sh | 92 ++++++++++++++++++- 1 file changed, 90 insertions(+), 2 deletions(-) diff --git a/tools/testing/selftests/tkernel/shield_mounts.sh b/tools/testing/selftests/tkernel/shield_mounts.sh index 23681c11c511..6c478fd1ecd6 100755 --- a/tools/testing/selftests/tkernel/shield_mounts.sh +++ b/tools/testing/selftests/tkernel/shield_mounts.sh @@ -4,10 +4,11 @@ KSFT_SKIP=4 PROC_FILE=/proc/tkernel/shield_mounts DEV_NAME=/dev/codex-shield -MOUNT_PATH=/mnt/codex-shield -TESTS=8 +MOUNT_PATH= +TESTS=14 test_no=0 failures=0 +mounted=0 script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd) helper="$script_dir/shield_mounts_test" @@ -29,6 +30,12 @@ result() fi } +result_skip() +{ + test_no=$((test_no + 1)) + echo "ok $test_no - $1 # SKIP $2" +} + entry_is_listed() { grep -Fqx "$DEV_NAME on $MOUNT_PATH" "$PROC_FILE" @@ -40,9 +47,49 @@ clear_entry() > "$PROC_FILE" 2>/dev/null || true } +mount_is_listed() +{ + grep -F "$MOUNT_PATH" "$1" | grep -Fq "$DEV_NAME" +} + +container_hides_mount() +{ + SHIELD_DEV_NAME="$DEV_NAME" SHIELD_MOUNT_PATH="$MOUNT_PATH" \ + unshare --mount --pid --fork --mount-proc sh -c ' + if grep -F "$SHIELD_MOUNT_PATH" /proc/self/mounts | + grep -Fq "$SHIELD_DEV_NAME"; then + exit 1 + fi + if grep -F "$SHIELD_MOUNT_PATH" /proc/self/mountinfo | + grep -Fq "$SHIELD_DEV_NAME"; then + exit 1 + fi + ' +} + +container_clear_restores_mount() +{ + SHIELD_DEV_NAME="$DEV_NAME" SHIELD_MOUNT_PATH="$MOUNT_PATH" \ + unshare --mount --pid --fork --mount-proc sh -c ' + printf "clear %s %s\n" "$SHIELD_DEV_NAME" \ + "$SHIELD_MOUNT_PATH" > /proc/tkernel/shield_mounts || + exit 1 + if grep -Fqx "$SHIELD_DEV_NAME on $SHIELD_MOUNT_PATH" \ + /proc/tkernel/shield_mounts; then + exit 1 + fi + grep -F "$SHIELD_MOUNT_PATH" /proc/self/mounts | + grep -Fq "$SHIELD_DEV_NAME" || exit 1 + grep -F "$SHIELD_MOUNT_PATH" /proc/self/mountinfo | + grep -Fq "$SHIELD_DEV_NAME" + ' +} + cleanup() { [ -e "$PROC_FILE" ] && clear_entry + [ "$mounted" -eq 1 ] && umount "$MOUNT_PATH" 2>/dev/null + [ -n "$MOUNT_PATH" ] && rmdir "$MOUNT_PATH" 2>/dev/null } echo "TAP version 13" @@ -51,6 +98,9 @@ echo "TAP version 13" [ -e "$PROC_FILE" ] || skip_all \ "CONFIG_TKERNEL_SHIELD_MOUNTS is not enabled" [ -x "$helper" ] || skip_all "shield_mounts_test helper is missing" +mkdir -p "${TMPDIR:-/tmp}" || skip_all "temporary directory is unavailable" +MOUNT_PATH=$(mktemp -d "${TMPDIR:-/tmp}/codex-shield.XXXXXX") || + skip_all "temporary mount point cannot be created" trap cleanup EXIT INT TERM clear_entry @@ -89,4 +139,42 @@ result "$listed_rc" "the escaped entry can be cleared" "$helper" "$PROC_FILE" result $? "a maximum-size trailing escape is rejected safely" +mount -t tmpfs "$DEV_NAME" "$MOUNT_PATH" +mount_rc=$? +if [ "$mount_rc" -eq 0 ]; then + mounted=1 +fi +result "$mount_rc" "a dedicated tmpfs mount can be created" + +printf 'set %s %s\n' "$DEV_NAME" "$MOUNT_PATH" > "$PROC_FILE" + +mount_is_listed /proc/self/mounts +result $? "the host PID namespace retains mounts visibility" + +mount_is_listed /proc/self/mountinfo +result $? "the host PID namespace retains mountinfo visibility" + +if command -v unshare >/dev/null 2>&1 && + unshare --mount --pid --fork --mount-proc true 2>/dev/null; then + container_hides_mount + result $? "a child mount and PID namespace hides the mount" + + container_clear_restores_mount + result $? "clear restores both container procfs mount views" + + if entry_is_listed; then + listed_rc=1 + else + listed_rc=0 + fi + result "$listed_rc" "the host observes the container clear" +else + result_skip "container mount visibility" \ + "mount and PID namespaces are unavailable" + result_skip "container clear restores procfs views" \ + "mount and PID namespaces are unavailable" + result_skip "host observes the container clear" \ + "mount and PID namespaces are unavailable" +fi + [ "$failures" -eq 0 ] -- Gitee