[PATCH v6 9/9] selftests/ftrace: Walk up to find test.d/functions when a subdirectory is passed

[email protected]
Newsgroups org.kernel.vger.linux-trace-kernel,org.kernel.vger.linux-kernel
Message-ID <dc58717cc225389b041dc36c684df23e3253c473.1787243842.git.wen.yang@linux.dev>
From: Wen Yang <[email protected]>

When a test directory that does not itself contain test.d/functions is
passed to ftracetest (e.g. verification/test.d/tlob/), ftracetest fell
back to its own functions file and lost the rv-specific check_requires
handling for ':monitor' and ':reactor' requirements.

Walk up the directory tree from OPT_TEST_DIR until a directory containing
test.d/functions is found. This allows monitor subdirectories to be passed
directly as the test root without placing a functions shim in each one.

The RV verification suite uses this so that

  tools/testing/selftests/verification/test.d/tlob/run_tlob_tests.sh

can pass test.d/tlob/ to ftracetest and have it source
verification/test.d/functions (which understands ':monitor'/':reactor').

Suggested-by: Gabriele Monaco <[email protected]>
Signed-off-by: Wen Yang <[email protected]>
---
 tools/testing/selftests/ftrace/ftracetest | 26 ++++++++++++++++++++---
 1 file changed, 23 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/ftrace/ftracetest b/tools/testing/selftests/ftrace/ftracetest
index 0a56bf209f6c..8f9d9291bf4c 100755
--- a/tools/testing/selftests/ftrace/ftracetest
+++ b/tools/testing/selftests/ftrace/ftracetest
@@ -159,9 +159,29 @@ parse_opts() { # opts
   if [ -n "$OPT_TEST_CASES" ]; then
     TEST_CASES=$OPT_TEST_CASES
   fi
-  if [ -n "$OPT_TEST_DIR" -a -f "$OPT_TEST_DIR"/test.d/functions ]; then
-    TOP_DIR=$OPT_TEST_DIR
-    TEST_DIR=$TOP_DIR/test.d
+  if [ -n "$OPT_TEST_DIR" ]; then
+    # Walk up from OPT_TEST_DIR to find the nearest ancestor that contains
+    # test.d/functions.  This allows a monitor subdirectory (e.g.
+    # verification/test.d/tlob/) to be passed directly without placing a
+    # dummy functions shim in each new subdirectory.
+    # Security: only walk within directories owned by root or the current user
+    # to prevent sourcing a functions file planted in a world-writable ancestor.
+    dir=$(realpath "$OPT_TEST_DIR" 2>/dev/null || echo "$OPT_TEST_DIR")
+    while [ "$dir" != "/" ] && [ "$dir" != "//" ]; do
+      if [ -f "$dir/test.d/functions" ]; then
+        # Verify the directory is not world-writable to prevent LPE.
+        dirperms=$(stat -c "%a" "$dir" 2>/dev/null || stat -f "%Lp" "$dir" 2>/dev/null)
+        case "$dirperms" in
+          *2|*3|*6|*7) ;; # world-writable: skip this candidate
+          *)
+            TOP_DIR=$dir
+            TEST_DIR=$TOP_DIR/test.d
+            break
+            ;;
+        esac
+      fi
+      dir=$(dirname "$dir")
+    done
   fi
 }
 
-- 
2.25.1
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.