Skip to content

Commit 6f59deb

Browse files
ahjf-07eddyz87
authored andcommitted
selftests/bpf: Cover negative buffer pointer offsets
Add verifier coverage for constant negative offsets on PTR_TO_TP_BUFFER and PTR_TO_BUF pointers. Both programs adjust the buffer pointer by -8 and access it at offset zero, so the negative effective start must be rejected at load time. Switch the raw tracepoint writable attach checks from nbd_send_request to bpf_testmod_test_writable_bare_tp, avoiding a dependency on the NBD tracepoint. Keep the existing past-end case and add a case with a negative var_off compensated by a positive instruction offset. The effective start remains non-negative, so the program loads, but its access end exceeds the writable context size and bpf_raw_tracepoint_open() must return -EINVAL. Cc: stable@vger.kernel.org # 5.2.0 Signed-off-by: Sun Jian <sun.jian.kdev@gmail.com> Acked-by: Shung-Hsi Yu <shung-hsi.yu@suse.com> Link: https://patch.msgid.link/20260714093846.18159-3-sun.jian.kdev@gmail.com Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
1 parent fd4cfa8 commit 6f59deb

5 files changed

Lines changed: 102 additions & 43 deletions

File tree

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
#include <test_progs.h>
4+
#include "test_kmods/bpf_testmod.h"
5+
#include "bpf_util.h"
6+
7+
static void check_attach_reject(const struct bpf_insn *program, size_t prog_len)
8+
{
9+
LIBBPF_OPTS(bpf_prog_load_opts, opts);
10+
char error[4096];
11+
int bpf_fd, tp_fd;
12+
13+
opts.log_level = 2;
14+
opts.log_buf = error;
15+
opts.log_size = sizeof(error);
16+
17+
bpf_fd = bpf_prog_load(BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE, NULL, "GPL v2",
18+
program, prog_len, &opts);
19+
if (!ASSERT_GE(bpf_fd, 0, "prog_load"))
20+
return;
21+
22+
tp_fd = bpf_raw_tracepoint_open("bpf_testmod_test_writable_bare_tp", bpf_fd);
23+
ASSERT_EQ(tp_fd, -EINVAL, "bpf_raw_tracepoint_open");
24+
if (tp_fd >= 0)
25+
close(tp_fd);
26+
27+
close(bpf_fd);
28+
}
29+
30+
void test_raw_tp_writable_reject_bad_access(void)
31+
{
32+
const struct bpf_insn program[] = {
33+
/* r6 is our tp buffer */
34+
BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
35+
/* one byte beyond the end of the writable context */
36+
BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6,
37+
sizeof(struct bpf_testmod_test_writable_ctx)),
38+
BPF_EXIT_INSN(),
39+
};
40+
41+
const struct bpf_insn negative_var_off_program[] = {
42+
BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
43+
/* make var_off negative, but keep the effective access offset non-negative */
44+
BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
45+
/* one byte beyond the end of the writable context */
46+
BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6,
47+
sizeof(struct bpf_testmod_test_writable_ctx) + 8),
48+
BPF_EXIT_INSN(),
49+
};
50+
51+
if (test__start_subtest("past_end"))
52+
check_attach_reject(program, ARRAY_SIZE(program));
53+
54+
if (test__start_subtest("negative_var_off_past_end"))
55+
check_attach_reject(negative_var_off_program,
56+
ARRAY_SIZE(negative_var_off_program));
57+
}

tools/testing/selftests/bpf/prog_tests/raw_tp_writable_reject_nbd_invalid.c

Lines changed: 0 additions & 43 deletions
This file was deleted.

tools/testing/selftests/bpf/prog_tests/verifier.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
#include "verifier_precision.skel.h"
7979
#include "verifier_prevent_map_lookup.skel.h"
8080
#include "verifier_private_stack.skel.h"
81+
#include "verifier_ptr_to_buf.skel.h"
8182
#include "verifier_raw_stack.skel.h"
8283
#include "verifier_raw_tp_writable.skel.h"
8384
#include "verifier_reg_equal.skel.h"
@@ -230,6 +231,7 @@ void test_verifier_or_jmp32_k(void) { RUN(verifier_or_jmp32_k); }
230231
void test_verifier_precision(void) { RUN(verifier_precision); }
231232
void test_verifier_prevent_map_lookup(void) { RUN(verifier_prevent_map_lookup); }
232233
void test_verifier_private_stack(void) { RUN(verifier_private_stack); }
234+
void test_verifier_ptr_to_buf(void) { RUN(verifier_ptr_to_buf); }
233235
void test_verifier_raw_stack(void) { RUN(verifier_raw_stack); }
234236
void test_verifier_raw_tp_writable(void) { RUN(verifier_raw_tp_writable); }
235237
void test_verifier_reg_equal(void) { RUN(verifier_reg_equal); }
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
3+
#include <vmlinux.h>
4+
#include <bpf/bpf_helpers.h>
5+
#include "bpf_misc.h"
6+
7+
SEC("iter/bpf_map_elem")
8+
__description("PTR_TO_BUF: reject negative const offset")
9+
__failure
10+
__msg("invalid negative rdwr buffer offset")
11+
__naked void ptr_to_buf_reject_negative_const_offset(void)
12+
{
13+
asm volatile ("r0 = 0; \
14+
r2 = *(u64 *)(r1 + %[value_off]); \
15+
if r2 == 0 goto l0_%=; \
16+
r2 += -8; \
17+
r0 = *(u64 *)(r2 + 0); \
18+
l0_%=: \
19+
exit; \
20+
"
21+
:
22+
: __imm_const(value_off,
23+
offsetof(struct bpf_iter__bpf_map_elem, value))
24+
: __clobber_all);
25+
}
26+
27+
char _license[] SEC("license") = "GPL";

tools/testing/selftests/bpf/progs/verifier_raw_tp_writable.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,20 @@ l0_%=: /* shift the buffer pointer to a variable location */\
4747
: __clobber_all);
4848
}
4949

50+
SEC("raw_tracepoint.w")
51+
__description("raw_tracepoint_writable: reject negative const offset")
52+
__failure
53+
__msg("invalid negative tracepoint buffer offset")
54+
__naked void tracepoint_writable_reject_negative_const_offset(void)
55+
{
56+
asm volatile (" \
57+
r6 = *(u64 *)(r1 + 0); \
58+
r6 += -8; \
59+
r0 = *(u64 *)(r6 + 0); \
60+
exit; \
61+
" :
62+
:
63+
: __clobber_all);
64+
}
65+
5066
char _license[] SEC("license") = "GPL";

0 commit comments

Comments
 (0)