Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F174524898
D59990.id187750.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D59990.id187750.diff
View Options
diff --git a/tests/sys/vfs/Makefile b/tests/sys/vfs/Makefile
--- a/tests/sys/vfs/Makefile
+++ b/tests/sys/vfs/Makefile
@@ -5,6 +5,8 @@
ATF_TESTS_C+= lookup_cap_dotdot
CFLAGS.lookup_cap_dotdot.c+= -I${SRCTOP}/tests
+ATF_TESTS_SH+= abi_root_symlink
+
#ATF_TESTS_SH+= lookup_test
TAP_TESTS_SH+= trailing_slash
diff --git a/tests/sys/vfs/abi_root_symlink.sh b/tests/sys/vfs/abi_root_symlink.sh
new file mode 100644
--- /dev/null
+++ b/tests/sys/vfs/abi_root_symlink.sh
@@ -0,0 +1,279 @@
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2026 Devin Teske <dteske@FreeBSD.org>
+#
+# Regression tests for absolute symlink resolution under an ABI root
+# (compat.linux.emul_path). namei(9) resolves paths for Linux ABI
+# processes by trying the ABI root first and falling back to the
+# native root. Absolute symlink targets receive the same treatment:
+# a target is first resolved under the ABI root (so self-contained
+# Linux userlands keep working, PR 289739); when the target itself
+# does not resolve there, the walk restarts once from the native
+# root using the expansion (so symlinks pointing at host paths, and
+# linprocfs' /proc/<pid>/exe, keep working, PR 297426). An ENOENT
+# past a target that did resolve under the ABI root falls back to
+# the original path like any other lookup.
+#
+# These tests require the Linux ABI (linux_enable=YES) and a Linux
+# userland (e.g. emulators/linux_base-rl9) providing ${emul_path}/bin/sh.
+# Without that, they skip, so CI jobs that lack a Linux base do not
+# fail. The two native-only cases still fail on CURRENT namei(9) and
+# use atf_expect_fail until the native-root retry lands (PR 297426).
+# Each case comments the fixture so it can be rebuilt by hand.
+# $wd is any empty directory (the ATF work directory when kyua
+# runs). $emul is compat.linux.emul_path, usually /compat/linux.
+# $emul$wd means the same path names created under that ABI root.
+#
+
+require_linux()
+{
+ emul=$(sysctl -n compat.linux.emul_path 2>/dev/null)
+ [ "$emul" ] || atf_skip "Linux ABI not present (compat.linux.emul_path)"
+ kldstat -q -m linux64 || kldstat -q -m linux ||
+ atf_skip "linux(4) not loaded"
+ lsh="$emul/bin/sh"
+ [ -x "$lsh" ] || atf_skip "Linux userland not installed ($lsh)"
+ # Mirror of the ATF work directory under the ABI root.
+ wd=$(pwd)
+ abiwd="$emul$wd"
+ atf_check mkdir -p "$abiwd"
+}
+
+cleanup_linux()
+{
+ emul=$(sysctl -n compat.linux.emul_path 2>/dev/null)
+ [ "$emul" ] || return 0
+ rm -rf "$emul$(pwd)" 2>/dev/null
+ # Remove now-empty parents mirrored under the ABI root.
+ rmdir -p "$emul$(dirname "$(pwd)")" 2>/dev/null
+ return 0
+}
+
+atf_test_case symlink_target_in_abi_root cleanup
+symlink_target_in_abi_root_head()
+{
+ atf_set "descr" "Absolute symlink target under the ABI root wins" \
+ "over an identically named native file (PR 289739)"
+ atf_set "require.user" "root"
+}
+symlink_target_in_abi_root_body()
+{
+ #
+ # Recreate by hand. $wd is any empty directory. $emul is
+ # compat.linux.emul_path (usually /compat/linux).
+ #
+ # Native:
+ # $wd/f-both
+ # Regular file containing the word "native".
+ #
+ # ABI (the same path names created under $emul):
+ # $emul$wd/f-both
+ # Regular file containing the word "abi".
+ # $emul$wd/link-both
+ # Absolute symlink whose target is $wd/f-both.
+ #
+ # A Linux process opens $wd/link-both. namei tries that path
+ # under the ABI root first ($emul$wd/link-both), follows the
+ # symlink to $wd/f-both, and stays on the ABI pass, so the
+ # file that is read is $emul$wd/f-both.
+ #
+ # Expected result: the read returns "abi".
+ #
+ require_linux
+ printf native > "$wd/f-both"
+ printf abi > "$abiwd/f-both"
+ atf_check ln -s "$wd/f-both" "$abiwd/link-both"
+ atf_check -o inline:"abi" "$lsh" -c "cat $wd/link-both"
+}
+symlink_target_in_abi_root_cleanup()
+{
+ cleanup_linux
+}
+
+atf_test_case symlink_target_native_only cleanup
+symlink_target_native_only_head()
+{
+ atf_set "descr" "Absolute symlink under the ABI root pointing at" \
+ "a native-only file falls back to the native root (PR 297426)"
+ atf_set "require.user" "root"
+}
+symlink_target_native_only_body()
+{
+ #
+ # Recreate by hand. $wd is any empty directory. $emul is
+ # compat.linux.emul_path (usually /compat/linux).
+ #
+ # Native:
+ # $wd/f-native
+ # Regular file containing the word "native".
+ #
+ # ABI (the same path names created under $emul):
+ # $emul$wd/link-native
+ # Absolute symlink whose target is $wd/f-native.
+ # There is no $emul$wd/f-native.
+ #
+ # A Linux process opens $wd/link-native. namei tries that
+ # path under the ABI root first ($emul$wd/link-native) and
+ # follows the symlink to $wd/f-native. That target does not
+ # exist under the ABI root, so the walk should restart once
+ # from the native root using the expansion and read
+ # $wd/f-native.
+ #
+ # Expected result: the read returns "native".
+ # On CURRENT namei this is ENOENT (atf_expect_fail; PR 297426).
+ #
+ require_linux
+ printf native > "$wd/f-native"
+ atf_check ln -s "$wd/f-native" "$abiwd/link-native"
+ atf_expect_fail \
+ "PR 297426: abs symlink to native-only target fails under ABI root"
+ atf_check -o inline:"native" "$lsh" -c "cat $wd/link-native"
+}
+symlink_target_native_only_cleanup()
+{
+ cleanup_linux
+}
+
+atf_test_case symlink_target_native_only_midpath cleanup
+symlink_target_native_only_midpath_head()
+{
+ atf_set "descr" "Absolute directory symlink under the ABI root" \
+ "pointing at a native-only directory falls back to the native" \
+ "root for lookups through it (PR 297426), as with" \
+ "linux-rl9-fontconfig's /etc/fonts -> /usr/local/etc/fonts"
+ atf_set "require.user" "root"
+}
+symlink_target_native_only_midpath_body()
+{
+ #
+ # Recreate by hand. $wd is any empty directory. $emul is
+ # compat.linux.emul_path (usually /compat/linux).
+ #
+ # Native:
+ # $wd/ndir/
+ # Directory.
+ # $wd/ndir/f
+ # Regular file containing the word "native".
+ #
+ # ABI (the same path names created under $emul):
+ # $emul$wd/dirlink
+ # Absolute symlink whose target is $wd/ndir.
+ # There is no $emul$wd/ndir.
+ #
+ # A Linux process opens $wd/dirlink/f. namei tries that path
+ # under the ABI root first ($emul$wd/dirlink/f), follows
+ # dirlink to $wd/ndir, and then wants $wd/ndir/f. The
+ # directory does not exist under the ABI root, so the walk
+ # should restart once from the native root using the
+ # expansion and read $wd/ndir/f. This is the
+ # linux-rl9-fontconfig case (/etc/fonts ->
+ # /usr/local/etc/fonts).
+ #
+ # Expected result: the read returns "native".
+ # On CURRENT namei this is ENOENT (atf_expect_fail; PR 297426).
+ #
+ require_linux
+ atf_check mkdir "$wd/ndir"
+ printf native > "$wd/ndir/f"
+ atf_check ln -s "$wd/ndir" "$abiwd/dirlink"
+ atf_expect_fail \
+ "PR 297426: abs dir symlink to native-only target fails under ABI root"
+ atf_check -o inline:"native" "$lsh" -c "cat $wd/dirlink/f"
+}
+symlink_target_native_only_midpath_cleanup()
+{
+ cleanup_linux
+}
+
+atf_test_case symlink_target_resolved_suffix cleanup
+symlink_target_resolved_suffix_head()
+{
+ atf_set "descr" "ENOENT past an absolute symlink target that" \
+ "resolved under the ABI root is not retried from the native" \
+ "root, even when the missing suffix exists natively"
+ atf_set "require.user" "root"
+}
+symlink_target_resolved_suffix_body()
+{
+ #
+ # Recreate by hand. $wd is any empty directory. $emul is
+ # compat.linux.emul_path (usually /compat/linux).
+ #
+ # Native:
+ # $wd/tdir/
+ # Directory.
+ # $wd/tdir/f
+ # Regular file containing the word "native".
+ #
+ # ABI (the same path names created under $emul):
+ # $emul$wd/tdir/
+ # Empty directory (no file named f).
+ # $emul$wd/reslink
+ # Absolute symlink whose target is $wd/tdir.
+ #
+ # A Linux process opens $wd/reslink/f. namei tries that path
+ # under the ABI root first ($emul$wd/reslink/f), follows
+ # reslink to $wd/tdir, and finds $emul$wd/tdir on the ABI
+ # pass. The leftover component f is missing there. Because
+ # the symlink target already resolved under the ABI root,
+ # the native restart must not walk the expansion (that would
+ # incorrectly find $wd/tdir/f). It restarts the original
+ # path and still gets ENOENT.
+ #
+ # Expected result: ENOENT.
+ #
+ require_linux
+ atf_check mkdir "$abiwd/tdir"
+ atf_check mkdir "$wd/tdir"
+ printf native > "$wd/tdir/f"
+ atf_check ln -s "$wd/tdir" "$abiwd/reslink"
+ atf_check -s not-exit:0 -e ignore "$lsh" -c "cat $wd/reslink/f"
+}
+symlink_target_resolved_suffix_cleanup()
+{
+ cleanup_linux
+}
+
+atf_test_case plain_native_fallback cleanup
+plain_native_fallback_head()
+{
+ atf_set "descr" "Plain path (no symlink) absent under the ABI root" \
+ "still falls back to the native root"
+ atf_set "require.user" "root"
+}
+plain_native_fallback_body()
+{
+ #
+ # Recreate by hand. $wd is any empty directory. $emul is
+ # compat.linux.emul_path (usually /compat/linux).
+ #
+ # Native:
+ # $wd/f-plain
+ # Regular file containing the word "native".
+ #
+ # ABI (the same path names created under $emul):
+ # There is no $emul$wd/f-plain, and no symlink.
+ #
+ # A Linux process opens $wd/f-plain. namei tries that path
+ # under the ABI root first, gets ENOENT, and restarts the
+ # original path from the native root.
+ #
+ # Expected result: the read returns "native".
+ #
+ require_linux
+ printf native > "$wd/f-plain"
+ atf_check -o inline:"native" "$lsh" -c "cat $wd/f-plain"
+}
+plain_native_fallback_cleanup()
+{
+ cleanup_linux
+}
+
+atf_init_test_cases()
+{
+ atf_add_test_case symlink_target_in_abi_root
+ atf_add_test_case symlink_target_native_only
+ atf_add_test_case symlink_target_native_only_midpath
+ atf_add_test_case symlink_target_resolved_suffix
+ atf_add_test_case plain_native_fallback
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Oct 4, 10:21 PM (16 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
39822480
Default Alt Text
D59990.id187750.diff (9 KB)
Attached To
Mode
D59990: tests/sys/vfs: add ABI-root absolute symlink tests
Attached
Detach File
Event Timeline
Log In to Comment