Re: [PATCH 2/3] selftests/syscall_user_dispatch: Skip tests if SUD is unsupported

2026-08-26 Thread Gregory Price
On Mon, Aug 17, 2026 at 12:16:10PM +0100, Christian Loehle wrote:
> Syscall User Dispatch is unavailable on architectures without generic
> syscall entry. Such architectures return -EINVAL for otherwise valid SUD
> prctl requests, causing sud_test to report failures.
> 
> This also prevents bad_prctl_param from providing useful coverage. The
> unsupported stub returns EINVAL before argument validation, so valid
> operations fail and requests expected to fail with EFAULT return EINVAL.
> 
> Probe SUD with a valid disabled configuration at the start of each test
> and skip when the kernel returns EINVAL. Preserve failures for unexpected
> errors and continue to run the full test on supported kernels.
> 

I suppose we should at least be testing for the EINVAL when not
supported, so this makes sense vs skipping the entire suite.

> Fixes: 179ef035992e ("selftests: Add kselftest for syscall user dispatch")
> Signed-off-by: Christian Loehle 

Reviewed-by: Gregory Price (Meta) 




[PATCH 2/3] selftests/syscall_user_dispatch: Skip tests if SUD is unsupported

2026-08-17 Thread Christian Loehle
Syscall User Dispatch is unavailable on architectures without generic
syscall entry. Such architectures return -EINVAL for otherwise valid SUD
prctl requests, causing sud_test to report failures.

This also prevents bad_prctl_param from providing useful coverage. The
unsupported stub returns EINVAL before argument validation, so valid
operations fail and requests expected to fail with EFAULT return EINVAL.

Probe SUD with a valid disabled configuration at the start of each test
and skip when the kernel returns EINVAL. Preserve failures for unexpected
errors and continue to run the full test on supported kernels.

Fixes: 179ef035992e ("selftests: Add kselftest for syscall user dispatch")
Signed-off-by: Christian Loehle 
---
 .../syscall_user_dispatch/sud_test.c  | 36 +++
 1 file changed, 36 insertions(+)

diff --git a/tools/testing/selftests/syscall_user_dispatch/sud_test.c 
b/tools/testing/selftests/syscall_user_dispatch/sud_test.c
index b855c6000287..1c84b86e24ba 100644
--- a/tools/testing/selftests/syscall_user_dispatch/sud_test.c
+++ b/tools/testing/selftests/syscall_user_dispatch/sud_test.c
@@ -41,6 +41,21 @@
 #define SYSCALL_DISPATCH_ON(x) ((x) = SYSCALL_DISPATCH_FILTER_BLOCK)
 #define SYSCALL_DISPATCH_OFF(x) ((x) = SYSCALL_DISPATCH_FILTER_ALLOW)
 
+static bool require_sud(struct __test_metadata *_metadata)
+{
+   int ret;
+
+   ret = prctl(PR_SET_SYSCALL_USER_DISPATCH, PR_SYS_DISPATCH_OFF,
+   0UL, 0UL, 0UL);
+   if (ret == -1 && errno == EINVAL)
+   SKIP(return false, "Syscall User Dispatch is not supported");
+   ASSERT_EQ(0, ret) {
+   TH_LOG("PR_SET_SYSCALL_USER_DISPATCH: %m");
+   }
+
+   return true;
+}
+
 /* Test Summary:
  *
  * - dispatch_trigger_sigsys: Verify if PR_SET_SYSCALL_USER_DISPATCH is
@@ -68,6 +83,9 @@ TEST_SIGNAL(dispatch_trigger_sigsys, SIGSYS)
struct sysinfo info;
int ret;
 
+   if (!require_sud(_metadata))
+   return;
+
ret = sysinfo(&info);
ASSERT_EQ(0, ret);
 
@@ -105,6 +123,9 @@ TEST(bad_prctl_param)
char sel = SYSCALL_DISPATCH_FILTER_ALLOW;
int op;
 
+   if (!require_sud(_metadata))
+   return;
+
/* Invalid op */
op = -1;
prctl_invalid(_metadata, op, 0, 0, &sel, EINVAL);
@@ -211,6 +232,9 @@ TEST(dispatch_and_return)
 {
long ret;
 
+   if (!require_sud(_metadata))
+   return;
+
glob_sel = 0;
nr_syscalls_emulated = 0;
si_code = 0;
@@ -259,6 +283,9 @@ TEST_SIGNAL(bad_selector, SIGSYS)
sigset_t mask;
struct sysinfo info;
 
+   if (!require_sud(_metadata))
+   return;
+
glob_sel = SYSCALL_DISPATCH_FILTER_ALLOW;
nr_syscalls_emulated = 0;
si_code = 0;
@@ -301,6 +328,9 @@ TEST(disable_dispatch)
struct sysinfo info;
char sel = 0;
 
+   if (!require_sud(_metadata))
+   return;
+
ret = prctl(PR_SET_SYSCALL_USER_DISPATCH, PR_SYS_DISPATCH_EXCLUSIVE_ON, 
0, 0, &sel);
ASSERT_EQ(0, ret) {
TH_LOG("Kernel does not support CONFIG_SYSCALL_USER_DISPATCH");
@@ -329,6 +359,9 @@ TEST(direct_dispatch_range)
struct sysinfo info;
char sel = SYSCALL_DISPATCH_FILTER_ALLOW;
 
+   if (!require_sud(_metadata))
+   return;
+
/*
 * Instead of calculating libc addresses; allow the entire
 * memory map and lock the selector.
@@ -365,6 +398,9 @@ static void test_range(struct __test_metadata *_metadata,
 
 TEST(dispatch_range)
 {
+   if (!require_sud(_metadata))
+   return;
+
ASSERT_EQ(0, setup_sigsys_handler());
test_range(_metadata, PR_SYS_DISPATCH_EXCLUSIVE_ON, 0, 0, true);
test_range(_metadata, PR_SYS_DISPATCH_EXCLUSIVE_ON, syscall_addr, 1, 
false);
-- 
2.34.1