On Fri, Aug 08, 2025 at 01:46:13AM +0800, Wake Liu wrote:
This commit introduces checks for kernel version and seccomp filter flag support to the seccomp selftests. It also includes conditional header inclusions using __GLIBC_PREREQ.
Some tests were gated by kernel version, and adjustments were made for flags introduced after kernel 5.4. This ensures the selftests can run and pass correctly on kernel versions 5.4 and later, preventing failures due to features not present in older kernels.
The use of __GLIBC_PREREQ ensures proper compilation and functionality across different glibc versions in a mainline Linux kernel context. While it might appear redundant in specific build environments due to global overrides, it is crucial for upstream correctness and portability.
Signed-off-by: Wake Liu wakel@google.com
tools/testing/selftests/seccomp/seccomp_bpf.c | 108 ++++++++++++++++-- 1 file changed, 99 insertions(+), 9 deletions(-)
diff --git a/tools/testing/selftests/seccomp/seccomp_bpf.c b/tools/testing/selftests/seccomp/seccomp_bpf.c index 61acbd45ffaa..9b660cff5a4a 100644 --- a/tools/testing/selftests/seccomp/seccomp_bpf.c +++ b/tools/testing/selftests/seccomp/seccomp_bpf.c @@ -13,12 +13,14 @@
- we need to use the kernel's siginfo.h file and trick glibc
- into accepting it.
*/ +#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) #if !__GLIBC_PREREQ(2, 26) # include <asm/siginfo.h> # define __have_siginfo_t 1 # define __have_sigval_t 1 # define __have_sigevent_t 1 #endif +#endif #include <errno.h> #include <linux/filter.h> @@ -300,6 +302,26 @@ int seccomp(unsigned int op, unsigned int flags, void *args) } #endif +int seccomp_flag_supported(int flag) +{
- /*
* Probes if a seccomp filter flag is supported by the kernel.
*
* When an unsupported flag is passed to seccomp(SECCOMP_SET_MODE_FILTER, ...),
* the kernel returns EINVAL.
*
* When a supported flag is passed, the kernel proceeds to validate the
* filter program pointer. By passing NULL for the filter program,
* the kernel attempts to dereference a bad address, resulting in EFAULT.
*
* Therefore, checking for EFAULT indicates that the flag itself was
* recognized and supported by the kernel.
*/
- if (seccomp(SECCOMP_SET_MODE_FILTER, flag, NULL) == -1 && errno == EFAULT)
return 1;
- return 0;
+}
I like this!
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ #define syscall_arg(_n) (offsetof(struct seccomp_data, args[_n])) #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ @@ -2436,13 +2458,12 @@ TEST(detect_seccomp_filter_flags) ASSERT_NE(ENOSYS, errno) { TH_LOG("Kernel does not support seccomp syscall!"); }
EXPECT_EQ(-1, ret);
EXPECT_EQ(EFAULT, errno) {
TH_LOG("Failed to detect that a known-good filter flag (0x%X) is supported!",
flag);
}
all_flags |= flag;
if (seccomp_flag_supported(flag))
all_flags |= flag;
else
TH_LOG("Filter flag (0x%X) is not found to be supported!",
flag);
So I've pushed back on "backward compatible" changes to this selftest because I want it to be validating the _latest_ seccomp. This allows for expected flags to be missing.
Is there perhaps a way that the backward compat checking could be a commandline flag or something? That way by default it looks strictly the more current seccomp features.
-Kees