All of lore.kernel.org
 help / color / mirror / Atom feed
From: Vineet Gupta <vineet.gupta@linux.dev>
To: bpf@vger.kernel.org
Cc: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org,
	eddyz87@gmail.com, memxor@gmail.com, martin.lau@linux.dev,
	song@kernel.org, yonghong.song@linux.dev, jolsa@kernel.org,
	emil@etsalapatis.com, ihor.solodrai@linux.dev,
	john.fastabend@gmail.com, shuah@kernel.org,
	linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org,
	jose.marchesi@oracle.com, david.faust@oss.qualcomm.com,
	Vineet Gupta <vineet.gupta@linux.dev>
Subject: [PATCH bpf-next v4 3/8] selftests/bpf: make arena_base() opaque to GCC's -Warray-bounds
Date: Tue,  3 Nov 2026 10:18:11 -0800	[thread overview]
Message-ID: <20261103181816.254686-4-vineet.gupta@linux.dev> (raw)
In-Reply-To: <20261103181816.254686-1-vineet.gupta@linux.dev>

arena_base() casts the map definition to the kernel's struct bpf_arena
and reads user_vm_start out of it. In the object file that definition
is only the 32-byte BTF placeholder the loader rewrites, so the access
is past the end of the object which GCC correctly complaints about and
due to -Werror leads to build failure:

  libarena/include/bpf_arena_common.h:52:69: error: array subscript 'struct bpf_arena[0]' is partly outside array bounds of 'struct <anonymous>[1]' [-Werror=array-bounds=]
     52 | #define arena_base(map) ((void __arena *)((struct bpf_arena *)(map))->user_vm_start)
  progs/arena_race.c:58:30: note: in expansion of macro 'arena_base'

progs/stream.c already solved this for its own open-coded copy of the
access, with barrier_var(), for both the compilers. Do the same in
arena_base() itself so all such uses are fixed.

No test changes verdict; this only lets the objects build.

Signed-off-by: Vineet Gupta <vineet.gupta@linux.dev>
---
v3 -> v4: was 4/8. barrier_var() for both compilers rather than
behind #ifdef __clang__, and stream.c's five open-coded copies of the
access fold back into the macro. (Alexei)

 .../bpf/libarena/include/bpf_arena_common.h   | 11 +++-
 tools/testing/selftests/bpf/progs/stream.c    | 56 +++----------------
 2 files changed, 18 insertions(+), 49 deletions(-)

diff --git a/tools/testing/selftests/bpf/libarena/include/bpf_arena_common.h b/tools/testing/selftests/bpf/libarena/include/bpf_arena_common.h
index 82aafe879fae..0eba52961405 100644
--- a/tools/testing/selftests/bpf/libarena/include/bpf_arena_common.h
+++ b/tools/testing/selftests/bpf/libarena/include/bpf_arena_common.h
@@ -49,7 +49,16 @@ void __arena* bpf_arena_alloc_pages(void *map, void __arena *addr, __u32 page_cn
 int bpf_arena_reserve_pages(void *map, void __arena *addr, __u32 page_cnt) __ksym __weak;
 void bpf_arena_free_pages(void *map, void __arena *ptr, __u32 page_cnt) __ksym __weak;
 
-#define arena_base(map) ((void __arena *)((struct bpf_arena *)(map))->user_vm_start)
+/*
+ * The map definition is smaller than struct bpf_arena.
+ * barrier_var() hides that from -Warray-bounds of GCC.
+ */
+#define arena_base(map)							\
+	({								\
+		struct bpf_arena *___arena = (void *)(map);		\
+		barrier_var(___arena);					\
+		(void __arena *)___arena->user_vm_start;		\
+	})
 
 #else /* when compiled as user space code */
 
diff --git a/tools/testing/selftests/bpf/progs/stream.c b/tools/testing/selftests/bpf/progs/stream.c
index 1ae015c4e6b4..b4d88d0e01ad 100644
--- a/tools/testing/selftests/bpf/progs/stream.c
+++ b/tools/testing/selftests/bpf/progs/stream.c
@@ -178,16 +178,8 @@ __stderr("Call trace:\n"
 "|[ \t]+[^\n]+\n)*}}")
 int stream_arena_write_fault(void *ctx)
 {
-	struct bpf_arena *ptr = (void *)&arena;
-	u64 user_vm_start;
+	u64 user_vm_start = (u64)arena_base(&arena);
 
-	/* Prevent GCC bounds warning: casting &arena to struct bpf_arena *
-	 * triggers bounds checking since the map definition is smaller than struct
-	 * bpf_arena. barrier_var() makes the pointer opaque to GCC, preventing the
-	 * bounds analysis
-	 */
-	barrier_var(ptr);
-	user_vm_start = ptr->user_vm_start;
 	fault_addr = user_vm_start + 0x7fff;
 	bpf_addr_space_cast(user_vm_start, 0, 1);
 	asm volatile (
@@ -212,16 +204,8 @@ __stderr("Call trace:\n"
 "|[ \t]+[^\n]+\n)*}}")
 int stream_arena_read_fault(void *ctx)
 {
-	struct bpf_arena *ptr = (void *)&arena;
-	u64 user_vm_start;
+	u64 user_vm_start = (u64)arena_base(&arena);
 
-	/* Prevent GCC bounds warning: casting &arena to struct bpf_arena *
-	 * triggers bounds checking since the map definition is smaller than struct
-	 * bpf_arena. barrier_var() makes the pointer opaque to GCC, preventing the
-	 * bounds analysis
-	 */
-	barrier_var(ptr);
-	user_vm_start = ptr->user_vm_start;
 	fault_addr = user_vm_start + 0x7fff;
 	bpf_addr_space_cast(user_vm_start, 0, 1);
 	asm volatile (
@@ -252,17 +236,9 @@ int stream_arena_load_acquire_fault(void *ctx)
 		.off	 = 0x7fff,
 		.imm	 = 0x100,	/* BPF_LOAD_ACQ */
 	};
-	struct bpf_arena *ptr = (void *)&arena;
-	u64 user_vm_start, val;
+	u64 user_vm_start = (u64)arena_base(&arena);
+	u64 val;
 
-	/*
-	 * Prevent GCC bounds warning: casting &arena to struct bpf_arena *
-	 * triggers bounds checking since the map definition is smaller than
-	 * struct bpf_arena. barrier_var() makes the pointer opaque to GCC,
-	 * preventing the bounds analysis.
-	 */
-	barrier_var(ptr);
-	user_vm_start = ptr->user_vm_start;
 	fault_addr = user_vm_start + 0x7fff;
 	bpf_addr_space_cast(user_vm_start, 0, 1);
 	asm volatile (
@@ -296,17 +272,9 @@ int stream_arena_xchg_fault(void *ctx)
 		.off	 = 0x7fff,
 		.imm	 = 0xe1,	/* BPF_XCHG */
 	};
-	struct bpf_arena *ptr = (void *)&arena;
-	u64 user_vm_start, val;
+	u64 user_vm_start = (u64)arena_base(&arena);
+	u64 val;
 
-	/*
-	 * Prevent GCC bounds warning: casting &arena to struct bpf_arena *
-	 * triggers bounds checking since the map definition is smaller than
-	 * struct bpf_arena. barrier_var() makes the pointer opaque to GCC,
-	 * preventing the bounds analysis.
-	 */
-	barrier_var(ptr);
-	user_vm_start = ptr->user_vm_start;
 	fault_addr = user_vm_start + 0x7fff;
 	bpf_addr_space_cast(user_vm_start, 0, 1);
 	/*
@@ -346,17 +314,9 @@ int stream_arena_cmpxchg_fault(void *ctx)
 		.off	 = 0x7fff,
 		.imm	 = 0xf1,	/* BPF_CMPXCHG */
 	};
-	struct bpf_arena *ptr = (void *)&arena;
-	u64 user_vm_start, val;
+	u64 user_vm_start = (u64)arena_base(&arena);
+	u64 val;
 
-	/*
-	 * Prevent GCC bounds warning: casting &arena to struct bpf_arena *
-	 * triggers bounds checking since the map definition is smaller than
-	 * struct bpf_arena. barrier_var() makes the pointer opaque to GCC,
-	 * preventing the bounds analysis.
-	 */
-	barrier_var(ptr);
-	user_vm_start = ptr->user_vm_start;
 	fault_addr = user_vm_start + 0x7fff;
 	bpf_addr_space_cast(user_vm_start, 0, 1);
 	/*
-- 
2.53.0-Meta


  parent reply	other threads:[~2026-11-03 18:18 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-03 18:18 [PATCH bpf-next v4 0/8] selftests/bpf: let the arena tests build with GCC Vineet Gupta
2026-11-03 18:18 ` [PATCH bpf-next v4 1/8] selftests/bpf: Build callx tests with GCC that defines __BPF_FEATURE_CALLX Vineet Gupta
2026-11-03 18:18 ` [PATCH bpf-next v4 2/8] selftests/bpf: don't pass clang-only warning flags to GCC Vineet Gupta
2026-11-03 18:18 ` Vineet Gupta [this message]
2026-11-03 18:18 ` [PATCH bpf-next v4 4/8] selftests/bpf: spell the addr_space_cast address spaces in decimal Vineet Gupta
2026-11-03 18:57   ` bot+bpf-ci
2026-11-03 18:18 ` [PATCH bpf-next v4 5/8] selftests/bpf: write the mixed arena/scalar ALU tests in asm Vineet Gupta
2026-11-03 18:57   ` bot+bpf-ci
2026-11-03 18:18 ` [PATCH bpf-next v4 6/8] selftests/bpf: drop the arena guards and tag the tests that need arena Vineet Gupta
2026-11-03 18:57   ` bot+bpf-ci
2026-11-03 18:18 ` [PATCH bpf-next v4 7/8] selftests/bpf: cast explicitly in the struct_ops arena triggers Vineet Gupta
2026-11-03 18:18 ` [PATCH bpf-next v4 8/8] selftests/bpf: cast explicitly in the arena subprog and callback faults Vineet Gupta
2026-11-03 21:20 ` [PATCH bpf-next v4 0/8] selftests/bpf: let the arena tests build with GCC patchwork-bot+netdevbpf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20261103181816.254686-4-vineet.gupta@linux.dev \
    --to=vineet.gupta@linux.dev \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=david.faust@oss.qualcomm.com \
    --cc=eddyz87@gmail.com \
    --cc=emil@etsalapatis.com \
    --cc=ihor.solodrai@linux.dev \
    --cc=john.fastabend@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=jose.marchesi@oracle.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=martin.lau@linux.dev \
    --cc=memxor@gmail.com \
    --cc=shuah@kernel.org \
    --cc=song@kernel.org \
    --cc=yonghong.song@linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.