From: Shung-Hsi Yu <shung-hsi.yu@suse.com>
To: sun jian <sun.jian.kdev@gmail.com>,
Eduard Zingerman <eddyz87@gmail.com>
Cc: bpf@vger.kernel.org, ast@kernel.org, daniel@iogearbox.net,
john.fastabend@gmail.com, andrii@kernel.org, memxor@gmail.com,
martin.lau@linux.dev, song@kernel.org, yonghong.song@linux.dev,
jolsa@kernel.org, emil@etsalapatis.com, shuah@kernel.org,
mmullins@fb.com, linux-kernel@vger.kernel.org,
linux-kselftest@vger.kernel.org
Subject: Re: [PATCH bpf v4 1/2] bpf: Reject negative const offsets for buffer pointers
Date: Mon, 13 Jul 2026 13:05:03 +0800 [thread overview]
Message-ID: <alRtilWhKw4zzMkI@u94a> (raw)
In-Reply-To: <CABFUUZEnd9f7tV-+jT+cgL7sFVp7pL5-tjdwMvxcR9ist1s-xg@mail.gmail.com>
On Fri, Jul 10, 2026 at 06:27:41PM +0800, sun jian wrote:
[...]
> One detail about the attach-time check: I agree that some negative-offset
> constructions can still be rejected later if the max_tp_access accounting
> produces a large value. But the runtime reproducer I used exercises this
> specific access:
>
> r6 = *(u64 *)(r1 + 0)
> r6 += -8
> *(u64 *)(r6 + 0) = 0
>
> Here reg->var_off.value is (u64)-8, off is 0, and size is 8. With the current
> accounting,
> reg->var_off.value + off + size
> wraps to 0. So max_tp_access records 0 and the attach-time writable_size check
> does not reject it, even though the effective access starts at -8.
Yes, that should had been rejected.
> On the bpf base without the verifier fix, the temporary reproducer did load
> and attach successfully:
> negative_bpf_load: PASS
> negative_raw_tp_open: PASS
> negative_test_run: PASS
> and KASAN reported the stack-out-of-bounds write in ___bpf_prog_run.
>
> So for this particular range, this looks like more than a load-time policy
> difference: the missing lower-bound check leaves the access executable on the
> bpf tree.
Actually I got this reproduced in the *bpf-next* tree now. And I think I
know why Eduard wasn't able to reproduce the issue.
The main problem was that CONFIG_BLK_DEV_NBD was not enabled in the
default BPF selftests configuration, so nbd_send_request wasn't
available, and thus the attachment always fail with -2 without
exercising the checks that we have in bpf_probe_register().
With CONFIG_BLK_DEV_NBD enabled, and negative_var_off_program[] updated
to do use offset of 0 (instead of 28 + 8), I was able to reproduce the
issue on top of commit `9a3a07d06e7d` "Merge branch
'bpf-fix-warning-in-bpf_trampoline_multi_detach'" with the following
updated version of your patch.
0: R1=ctx() R10=fp0
0: (79) r6 = *(u64 *)(r1 +0) ; R1=ctx() R6=tp_buffer()
1: (07) r6 += -8 ; R6=tp_buffer(imm=-8)
2: (79) r0 = *(u64 *)(r6 +0) ; R0=scalar() R6=tp_buffer(imm=-8)
3: (95) exit
processed 4 insns (limit 1000000) max_states_per_insn 0 total_states 0 peak_states 0 mark_read 0
tp_fd: 8
check_nbd_attach_reject:FAIL:nbd_invalid_negative_var_off unexpected nbd_invalid_negative_var_off: actual 8 >= expected 0
#319 raw_tp_writable_reject_nbd_invalid:FAIL
So I would say a fixes tag that points to 022ac0750883 is still needed
after all.
---
diff --git a/tools/testing/selftests/bpf/config b/tools/testing/selftests/bpf/config
index adb25146e88c..e1797bd87904 100644
--- a/tools/testing/selftests/bpf/config
+++ b/tools/testing/selftests/bpf/config
@@ -1,4 +1,5 @@
CONFIG_BLK_DEV_LOOP=y
+CONFIG_BLK_DEV_NBD=y
CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y
CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=1
CONFIG_BPF=y
diff --git a/tools/testing/selftests/bpf/prog_tests/raw_tp_writable_reject_nbd_invalid.c b/tools/testing/selftests/bpf/prog_tests/raw_tp_writable_reject_nbd_invalid.c
index 216b0dfac0fe..0ed1d560a2f4 100644
--- a/tools/testing/selftests/bpf/prog_tests/raw_tp_writable_reject_nbd_invalid.c
+++ b/tools/testing/selftests/bpf/prog_tests/raw_tp_writable_reject_nbd_invalid.c
@@ -4,12 +4,34 @@
#include <linux/nbd.h>
#include "bpf_util.h"
+static void check_nbd_attach_reject(const char *name,
+ const struct bpf_insn *program, size_t prog_len)
+{
+ LIBBPF_OPTS(bpf_prog_load_opts, opts);
+ char error[8192];
+ int bpf_fd, tp_fd;
+
+ opts.log_level = 2;
+ opts.log_buf = error;
+ opts.log_size = sizeof(error);
+
+ bpf_fd = bpf_prog_load(BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE, NULL, "GPL v2",
+ program, prog_len, &opts);
+ if (!ASSERT_GE(bpf_fd, 0, "prog_load"))
+ return;
+
+ printf("verifier log: %s", error);
+
+ tp_fd = bpf_raw_tracepoint_open("nbd_send_request", bpf_fd);
+ printf("tp_fd: %d\n", tp_fd);
+ if (!ASSERT_LT(tp_fd, 0, name))
+ close(tp_fd);
+
+ close(bpf_fd);
+}
+
void test_raw_tp_writable_reject_nbd_invalid(void)
{
- __u32 duration = 0;
- char error[4096];
- int bpf_fd = -1, tp_fd = -1;
-
const struct bpf_insn program[] = {
/* r6 is our tp buffer */
BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
@@ -19,25 +41,17 @@ void test_raw_tp_writable_reject_nbd_invalid(void)
BPF_EXIT_INSN(),
};
- LIBBPF_OPTS(bpf_prog_load_opts, opts,
- .log_level = 2,
- .log_buf = error,
- .log_size = sizeof(error),
- );
+ const struct bpf_insn negative_var_off_program[] = {
+ /* r6 is our tp buffer */
+ BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 0),
+ /* eight bytes before the start of the nbd_request struct */
+ BPF_ALU64_IMM(BPF_ADD, BPF_REG_6, -8),
+ BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_6, 0),
+ BPF_EXIT_INSN(),
+ };
- bpf_fd = bpf_prog_load(BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE, NULL, "GPL v2",
- program, ARRAY_SIZE(program),
- &opts);
- if (CHECK(bpf_fd < 0, "bpf_raw_tracepoint_writable load",
- "failed: %d errno %d\n", bpf_fd, errno))
- return;
-
- tp_fd = bpf_raw_tracepoint_open("nbd_send_request", bpf_fd);
- if (CHECK(tp_fd >= 0, "bpf_raw_tracepoint_writable open",
- "erroneously succeeded\n"))
- goto out_bpffd;
-
- close(tp_fd);
-out_bpffd:
- close(bpf_fd);
+ check_nbd_attach_reject("nbd_invalid", program, ARRAY_SIZE(program));
+ check_nbd_attach_reject("nbd_invalid_negative_var_off",
+ negative_var_off_program,
+ ARRAY_SIZE(negative_var_off_program));
}
next prev parent reply other threads:[~2026-07-13 5:05 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-08 9:01 [PATCH bpf v4 0/2] bpf: Reject negative const offsets for buffer pointers Sun Jian
2026-07-08 9:01 ` [PATCH bpf v4 1/2] " Sun Jian
2026-07-08 13:13 ` Shung-Hsi Yu
2026-07-08 14:11 ` sun jian
2026-07-09 6:47 ` Shung-Hsi Yu
2026-07-09 12:47 ` sun jian
2026-07-09 18:21 ` Eduard Zingerman
2026-07-10 5:52 ` sun jian
2026-07-10 6:23 ` Eduard Zingerman
2026-07-10 7:25 ` sun jian
2026-07-10 7:47 ` Eduard Zingerman
2026-07-10 8:00 ` Shung-Hsi Yu
2026-07-10 8:10 ` Shung-Hsi Yu
2026-07-10 10:27 ` sun jian
2026-07-13 5:05 ` Shung-Hsi Yu [this message]
2026-07-08 9:01 ` [PATCH bpf v4 2/2] selftests/bpf: Cover negative raw_tp writable buffer offsets Sun Jian
2026-07-09 16:59 ` Eduard Zingerman
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=alRtilWhKw4zzMkI@u94a \
--to=shung-hsi.yu@suse.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=emil@etsalapatis.com \
--cc=john.fastabend@gmail.com \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=mmullins@fb.com \
--cc=shuah@kernel.org \
--cc=song@kernel.org \
--cc=sun.jian.kdev@gmail.com \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox