lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250814160740.96150-4-phoenix500526@163.com>
Date: Thu, 14 Aug 2025 16:07:39 +0000
From: Jiawei Zhao <phoenix500526@....com>
To: ast@...nel.org
Cc: daniel@...earbox.net,
	andrii@...nel.org,
	yonghong.song@...ux.dev,
	bpf@...r.kernel.org,
	linux-kselftest@...r.kernel.org,
	linux-kernel@...r.kernel.org
Subject: [PATCH bpf-next v10 3/3] selftests/bpf: make usdt_o2 reliably generate SIB USDT arg spec

usdt_o2 is intended to exercise the SIB (Scale-Index-Base) argument
handling in libbpf's USDT path. With GCC 13 this reliably produced a
SIB-form argument (e.g. 8@(%rdx,%rax,8)), but with newer GCC (e.g. 15)
the compiler frequently optimizes the probe argument into a plain
register (e.g. 8@...x) or a stack slot, so the test stops covering the
SIB code path and becomes flaky across toolchains.

Force a SIB memory operand in the probe by:
* placing the base pointer into %rdx and the index into %rax using an
  empty inline asm with output constraints ("=d", "=a") and matching
  inputs
* immediately passing base[idx] to STAP_PROBE1.
* only enable on x86 platform.

This makes the compiler encode the operand as SIB (base + index8),
which in .note.stapsdt shows up as 8@(%rdx,%rax,8) regardless of GCC
version. A memory clobber and noinline prevent reordering/re-allocation
around the probe site.

This change is x86_64-specific and does not alter program semantics; it
only stabilizes the USDT argument shape so the test consistently
validates SIB handling. Clang historically prefers stack temporaries for
such operands, but the selftests build with GCC, and this keeps behavior
stable across GCC versions without introducing a separate .S file.

Signed-off-by: Jiawei Zhao <phoenix500526@....com>
---
 .../selftests/bpf/prog_tests/usdt_o2.c        | 20 ++++++++++++++-----
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/usdt_o2.c b/tools/testing/selftests/bpf/prog_tests/usdt_o2.c
index f02dcf5188ab..e46d5743ad24 100644
--- a/tools/testing/selftests/bpf/prog_tests/usdt_o2.c
+++ b/tools/testing/selftests/bpf/prog_tests/usdt_o2.c
@@ -15,11 +15,19 @@ __attribute__((optimize("O2")))
 int lets_test_this(int);
 static volatile __u64 array[1] = {test_value};
 
-static __always_inline void trigger_func(void)
+static noinline void trigger_func(void)
 {
+#if defined(__x86_64__) || defined(__i386__)
 	/* Base address + offset + (index * scale) */
-	for (volatile int i = 0; i <= 0; i++)
-		STAP_PROBE1(test, usdt1, array[i]);
+	/* Force SIB addressing with inline assembly */
+	const __u64 *base;
+	__u32 idx;
+	/* binding base to %rdx and idx to %rax */
+	asm volatile("" : "=d"(base), "=a"(idx) : "0"(array), "1"((__u32)0) : "memory");
+	STAP_PROBE1(test, usdt1, base[idx]);
+#else
+	STAP_PROBE1(test, usdt1, array[0]);
+#endif
 }
 
 static void basic_sib_usdt(void)
@@ -61,9 +69,11 @@ static void basic_sib_usdt(void)
 	test_usdt_o2__destroy(skel);
 }
 
-
-
 void test_usdt_o2(void)
 {
+#if !defined(__x86_64__) && !defined(__i386__)
+	test__skip();
+	return;
+#endif
 	basic_sib_usdt();
 }
-- 
2.43.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ