From 11d12a82fb937589f8121ff038df8ceaf20e3c56 Mon Sep 17 00:00:00 2001 From: Mark Meserve Date: Mon, 10 Nov 2025 09:15:50 -0600 Subject: [PATCH] rocprofiler-sdk: attach: fix test permissions (#1528) * attach: fix test permissions - Test is now skipped if insufficient permissions detected - Should fix test (for now) in Azure CI pipeline - Add more extensive permission checking for the tests - Add default parameters to prevent running rm -rf on a root directory - Add use for unused LOG_LEVEL parameter --- .../attachment/attach-once/CMakeLists.txt | 12 ++++++++-- .../attachment/attach-once/conftest.py | 10 ++++++++ .../run_attachment_test_unified.sh | 23 +++++++++++++++---- .../attachment/attach-twice/CMakeLists.txt | 12 ++++++++-- .../attachment/attach-twice/conftest.py | 10 ++++++++ .../run_attachment_test_unified.sh | 23 +++++++++++++++---- 6 files changed, 78 insertions(+), 12 deletions(-) diff --git a/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-once/CMakeLists.txt b/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-once/CMakeLists.txt index f407ee3cc9..aa74876a43 100644 --- a/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-once/CMakeLists.txt +++ b/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-once/CMakeLists.txt @@ -53,6 +53,8 @@ set_tests_properties( "${attachment-env}" FAIL_REGULAR_EXPRESSION "ERROR|FATAL|${ROCPROFILER_DEFAULT_FAIL_REGEX}" + SKIP_REGULAR_EXPRESSION + "This test is skipped." FIXTURES_SETUP rocprofv3-test-attachment-attach-once DISABLED @@ -67,7 +69,8 @@ add_test( ${CMAKE_CURRENT_BINARY_DIR}/attachment-output/out_hsa_api_trace.csv --memory-copy-input ${CMAKE_CURRENT_BINARY_DIR}/attachment-output/out_memory_copy_trace.csv - --agent-input ${CMAKE_CURRENT_BINARY_DIR}/attachment-output/out_agent_info.csv) + --agent-input ${CMAKE_CURRENT_BINARY_DIR}/attachment-output/out_agent_info.csv + --skip-if ${CMAKE_CURRENT_BINARY_DIR}/attachment-output/skipped) set_tests_properties( rocprofv3-test-attachment-attach-once-csv-validate @@ -77,6 +80,8 @@ set_tests_properties( "integration-tests;attachment" DEPENDS rocprofv3-test-attachment-attach-once-execute + SKIP_REGULAR_EXPRESSION + "SKIPPED" FIXTURES_REQUIRED rocprofv3-test-attachment-attach-once DISABLED @@ -90,7 +95,8 @@ add_test( ${CMAKE_CURRENT_BINARY_DIR}/attachment-output/out_results.json --memory-copy-input ${CMAKE_CURRENT_BINARY_DIR}/attachment-output/out_results.json --agent-input - ${CMAKE_CURRENT_BINARY_DIR}/attachment-output/out_results.json) + ${CMAKE_CURRENT_BINARY_DIR}/attachment-output/out_results.json --skip-if + ${CMAKE_CURRENT_BINARY_DIR}/attachment-output/skipped) set_tests_properties( rocprofv3-test-attachment-attach-once-json-validate @@ -100,6 +106,8 @@ set_tests_properties( "integration-tests;attachment" DEPENDS rocprofv3-test-attachment-attach-once-execute + SKIP_REGULAR_EXPRESSION + "SKIPPED" FIXTURES_REQUIRED rocprofv3-test-attachment-attach-once DISABLED diff --git a/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-once/conftest.py b/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-once/conftest.py index 81afbe5e77..9271149f33 100644 --- a/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-once/conftest.py +++ b/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-once/conftest.py @@ -25,6 +25,7 @@ import csv import json import pytest +import os def pytest_addoption(parser): @@ -34,6 +35,7 @@ def pytest_addoption(parser): ) parser.addoption("--hsa-input", action="store", help="HSA API trace input") parser.addoption("--agent-input", action="store", help="Agent info input") + parser.addoption("--skip-if", action="store", help="Skip test if file exists") def get_data(request, field, section_name): @@ -218,19 +220,27 @@ def get_csv_data(file_path): @pytest.fixture def kernel_input_data(request): + if os.path.exists(request.config.getoption("--skip-if")): + pytest.skip("Attach tests unavailable due to insufficient ptrace permissions") return get_data(request, "--kernel-input", "kernel_dispatch") @pytest.fixture def memory_copy_input_data(request): + if os.path.exists(request.config.getoption("--skip-if")): + pytest.skip("Attach tests unavailable due to insufficient ptrace permissions") return get_data(request, "--memory-copy-input", "memory_copy") @pytest.fixture def hsa_input_data(request): + if os.path.exists(request.config.getoption("--skip-if")): + pytest.skip("Attach tests unavailable due to insufficient ptrace permissions") return get_data(request, "--hsa-input", "hsa_api") @pytest.fixture def agent_info_input_data(request): + if os.path.exists(request.config.getoption("--skip-if")): + pytest.skip("Attach tests unavailable due to insufficient ptrace permissions") return get_data(request, "--agent-input", "agent_info") diff --git a/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-once/run_attachment_test_unified.sh b/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-once/run_attachment_test_unified.sh index e90f1b53db..e632dafbd6 100755 --- a/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-once/run_attachment_test_unified.sh +++ b/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-once/run_attachment_test_unified.sh @@ -27,8 +27,8 @@ set -e # Arguments TEST_APP=$1 ROCPROFV3=$2 -OUTPUT_DIR=$3 -LOG_LEVEL=$4 +OUTPUT_DIR=${3:-${PWD}} +LOG_LEVEL=${4:-info} OUTPUT_FILENAME=${5:-out} # Set environment variables required for attachment @@ -44,6 +44,21 @@ OUTPUT_FORMAT="csv json rocpd" rm -rf ${OUTPUT_DIR}/${OUTPUT_SUBDIR} mkdir -p ${OUTPUT_DIR}/${OUTPUT_SUBDIR} +# Check for permissions. We need to be able to ptrace any process in the system. (ptrace_scope == 0) +# First, if the ptrace_scope variable is not present, we assume there is no restriction and we can proceed normally. +# Next, if ptrace_scope would disallow this test, also confirm we are not root (which would allow it anyways.) (id -u != 0) +# Finally, confirm this process or python3 doesn't have CAP_SYS_PTRACE, which would allow the test also. +if [ -e /proc/sys/kernel/yama/ptrace_scope ] \ +&& [ $(cat /proc/sys/kernel/yama/ptrace_scope) -ne 0 ] \ +&& [ $(id -u) -ne 0 ] \ +&& [[ $(getpcaps self) != *"cap_sys_ptrace"* ]] \ +&& [[ $(getcap $(readlink -f $(which python3))) != *"cap_sys_ptrace"* ]] + then + echo "ptrace_scope is not 0, user is not root, and CAP_SYS_PTRACE is not present, so test cannot be completed. This test is skipped." + touch ${OUTPUT_DIR}/${OUTPUT_SUBDIR}/skipped + exit 0 +fi + echo "Starting attachment test (${OUTPUT_FORMAT} format)..." # Start the test application in the background @@ -72,7 +87,7 @@ echo "Attaching profiler to PID $APP_PID for 5 seconds (${OUTPUT_FORMAT} format) # Output the command and environment for debugging echo "===== COMMAND TO EXECUTE =====" -echo "${ROCPROFV3} --attach $APP_PID --attach-duration-msec 5000 -s -f ${OUTPUT_FORMAT} --stats --summary --group-by-queue -d ${OUTPUT_DIR}/${OUTPUT_SUBDIR} -o ${OUTPUT_FILENAME:-out}" +echo "${ROCPROFV3} --attach $APP_PID --attach-duration-msec 5000 -s -f ${OUTPUT_FORMAT} --stats --summary --group-by-queue -d ${OUTPUT_DIR}/${OUTPUT_SUBDIR} --log-level ${LOG_LEVEL} -o ${OUTPUT_FILENAME:-out}" echo "" echo "===== ENVIRONMENT VARIABLES =====" env | sort @@ -80,7 +95,7 @@ echo "===== END ENVIRONMENT =====" echo "" # Run rocprofv3 with --attach option -LD_PRELOAD=${ROCPROF_PRELOAD} ${ROCPROFV3} --attach $APP_PID --attach-duration-msec 5000 -s -f ${OUTPUT_FORMAT} --stats --summary --group-by-queue -d ${OUTPUT_DIR}/${OUTPUT_SUBDIR} -o ${OUTPUT_FILENAME:-out} +LD_PRELOAD=${ROCPROF_PRELOAD} ${ROCPROFV3} --attach $APP_PID --attach-duration-msec 5000 -s -f ${OUTPUT_FORMAT} --stats --summary --group-by-queue -d ${OUTPUT_DIR}/${OUTPUT_SUBDIR} --log-level ${LOG_LEVEL} -o ${OUTPUT_FILENAME:-out} echo "${OUTPUT_FORMAT} profiler detached successfully" diff --git a/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-twice/CMakeLists.txt b/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-twice/CMakeLists.txt index 128eeac609..b10667dab9 100644 --- a/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-twice/CMakeLists.txt +++ b/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-twice/CMakeLists.txt @@ -53,6 +53,8 @@ set_tests_properties( "${attachment-env}" FAIL_REGULAR_EXPRESSION "ERROR|FATAL|${ROCPROFILER_DEFAULT_FAIL_REGEX}" + SKIP_REGULAR_EXPRESSION + "This test is skipped." FIXTURES_SETUP rocprofv3-test-attachment-attach-twice DISABLED @@ -67,7 +69,8 @@ add_test( ${CMAKE_CURRENT_BINARY_DIR}/attachment-output/out_hsa_api_trace.csv --memory-copy-input ${CMAKE_CURRENT_BINARY_DIR}/attachment-output/out_memory_copy_trace.csv - --agent-input ${CMAKE_CURRENT_BINARY_DIR}/attachment-output/out_agent_info.csv) + --agent-input ${CMAKE_CURRENT_BINARY_DIR}/attachment-output/out_agent_info.csv + --skip-if ${CMAKE_CURRENT_BINARY_DIR}/attachment-output/skipped) set_tests_properties( rocprofv3-test-attachment-attach-twice-csv-validate @@ -77,6 +80,8 @@ set_tests_properties( "integration-tests;attachment" DEPENDS rocprofv3-test-attachment-attach-twice-execute + SKIP_REGULAR_EXPRESSION + "SKIPPED" FIXTURES_REQUIRED rocprofv3-test-attachment-attach-twice DISABLED @@ -90,7 +95,8 @@ add_test( ${CMAKE_CURRENT_BINARY_DIR}/attachment-output/out_results.json --memory-copy-input ${CMAKE_CURRENT_BINARY_DIR}/attachment-output/out_results.json --agent-input - ${CMAKE_CURRENT_BINARY_DIR}/attachment-output/out_results.json) + ${CMAKE_CURRENT_BINARY_DIR}/attachment-output/out_results.json --skip-if + ${CMAKE_CURRENT_BINARY_DIR}/attachment-output/skipped) set_tests_properties( rocprofv3-test-attachment-attach-twice-json-validate @@ -100,6 +106,8 @@ set_tests_properties( "integration-tests;attachment" DEPENDS rocprofv3-test-attachment-attach-twice-execute + SKIP_REGULAR_EXPRESSION + "SKIPPED" FIXTURES_REQUIRED rocprofv3-test-attachment-attach-twice DISABLED diff --git a/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-twice/conftest.py b/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-twice/conftest.py index b5531add62..1df0b023d2 100644 --- a/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-twice/conftest.py +++ b/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-twice/conftest.py @@ -25,6 +25,7 @@ import csv import json import pytest +import os def pytest_addoption(parser): @@ -34,6 +35,7 @@ def pytest_addoption(parser): ) parser.addoption("--hsa-input", action="store", help="HSA API trace input") parser.addoption("--agent-input", action="store", help="Agent info input") + parser.addoption("--skip-if", action="store", help="Skip test if file exists") def get_data(request, field, section_name): @@ -218,19 +220,27 @@ def get_csv_data(file_path): @pytest.fixture def kernel_input_data(request): + if os.path.exists(request.config.getoption("--skip-if")): + pytest.skip("Attach tests unavailable due to insufficient ptrace permissions") return get_data(request, "--kernel-input", "kernel_dispatch") @pytest.fixture def memory_copy_input_data(request): + if os.path.exists(request.config.getoption("--skip-if")): + pytest.skip("Attach tests unavailable due to insufficient ptrace permissions") return get_data(request, "--memory-copy-input", "memory_copy") @pytest.fixture def hsa_input_data(request): + if os.path.exists(request.config.getoption("--skip-if")): + pytest.skip("Attach tests unavailable due to insufficient ptrace permissions") return get_data(request, "--hsa-input", "hsa_api") @pytest.fixture def agent_info_input_data(request): + if os.path.exists(request.config.getoption("--skip-if")): + pytest.skip("Attach tests unavailable due to insufficient ptrace permissions") return get_data(request, "--agent-input", "agent_info") diff --git a/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-twice/run_attachment_test_unified.sh b/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-twice/run_attachment_test_unified.sh index fbb8d96b48..9ba948463e 100755 --- a/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-twice/run_attachment_test_unified.sh +++ b/projects/rocprofiler-sdk/tests/rocprofv3/attachment/attach-twice/run_attachment_test_unified.sh @@ -27,8 +27,8 @@ set -e # Arguments TEST_APP=$1 ROCPROFV3=$2 -OUTPUT_DIR=$3 -LOG_LEVEL=$4 +OUTPUT_DIR=${3:-${PWD}} +LOG_LEVEL=${4:-info} OUTPUT_FILENAME=${5:-out} # Set environment variables required for attachment @@ -43,6 +43,21 @@ OUTPUT_FORMAT="csv json rocpd" rm -rf ${OUTPUT_DIR}/${OUTPUT_SUBDIR} mkdir -p ${OUTPUT_DIR}/${OUTPUT_SUBDIR} +# Check for permissions. We need to be able to ptrace any process in the system. (ptrace_scope == 0) +# First, if the ptrace_scope variable is not present, we assume there is no restriction and we can proceed normally. +# Next, if ptrace_scope would disallow this test, also confirm we are not root (which would allow it anyways.) (id -u != 0) +# Finally, confirm this process or python3 doesn't have CAP_SYS_PTRACE, which would allow the test also. +if [ -e /proc/sys/kernel/yama/ptrace_scope ] \ +&& [ $(cat /proc/sys/kernel/yama/ptrace_scope) -ne 0 ] \ +&& [ $(id -u) -ne 0 ] \ +&& [[ $(getpcaps self) != *"cap_sys_ptrace"* ]] \ +&& [[ $(getcap $(readlink -f $(which python3))) != *"cap_sys_ptrace"* ]] + then + echo "ptrace_scope is not 0, user is not root, and CAP_SYS_PTRACE is not present, so test cannot be completed. This test is skipped." + touch ${OUTPUT_DIR}/${OUTPUT_SUBDIR}/skipped + exit 0 +fi + echo "Starting attachment test (${OUTPUT_FORMAT} format)..." # Start the test application in the background @@ -74,7 +89,7 @@ echo "First attachment: Attaching profiler to PID $APP_PID for 5 seconds (${OUTP # Run first rocprofv3 with --attach option echo "About to launch first rocprofv3 process..." -LD_PRELOAD=${ROCPROF_PRELOAD} ${ROCPROFV3} --attach $APP_PID --attach-duration-msec 5000 -s -f ${OUTPUT_FORMAT} -d ${OUTPUT_DIR}/${OUTPUT_SUBDIR} -o ${OUTPUT_FILENAME:-out} & +LD_PRELOAD=${ROCPROF_PRELOAD} ${ROCPROFV3} --attach $APP_PID --attach-duration-msec 5000 -s -f ${OUTPUT_FORMAT} -d ${OUTPUT_DIR}/${OUTPUT_SUBDIR} --log-level ${LOG_LEVEL} -o ${OUTPUT_FILENAME:-out} & FIRST_ROCPROF_PID=$! ATTACH_PID=$FIRST_ROCPROF_PID echo "First rocprofv3 PID: $FIRST_ROCPROF_PID" @@ -122,7 +137,7 @@ echo "Second attachment: Attaching profiler to PID $APP_PID for 5 seconds (${OUT # Run second rocprofv3 with --attach option echo "About to launch second rocprofv3 process..." -LD_PRELOAD=${ROCPROF_PRELOAD} ${ROCPROFV3} --attach $APP_PID --attach-duration-msec 5000 -s -f ${OUTPUT_FORMAT} -d ${OUTPUT_DIR}/${OUTPUT_SUBDIR} -o ${OUTPUT_FILENAME:-out} & +LD_PRELOAD=${ROCPROF_PRELOAD} ${ROCPROFV3} --attach $APP_PID --attach-duration-msec 5000 -s -f ${OUTPUT_FORMAT} -d ${OUTPUT_DIR}/${OUTPUT_SUBDIR} --log-level ${LOG_LEVEL} -o ${OUTPUT_FILENAME:-out} & SECOND_ROCPROF_PID=$! ATTACH_PID=$SECOND_ROCPROF_PID echo "Second rocprofv3 PID: $SECOND_ROCPROF_PID"