All of lore.kernel.org
 help / color / mirror / Atom feed
From: KaFai Wan <kafai.wan@linux.dev>
To: Brahmajit Das <listout@listout.xyz>,
	Alexei Starovoitov <alexei.starovoitov@gmail.com>
Cc: syzbot+d36d5ae81e1b0a53ef58@syzkaller.appspotmail.com,
	Andrii Nakryiko <andrii@kernel.org>,
	Alexei Starovoitov <ast@kernel.org>, bpf <bpf@vger.kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>,
	Eduard <eddyz87@gmail.com>, Hao Luo <haoluo@google.com>,
	John Fastabend <john.fastabend@gmail.com>,
	Jiri Olsa <jolsa@kernel.org>, KP Singh <kpsingh@kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Martin KaFai Lau <martin.lau@linux.dev>,
	Stanislav Fomichev <sdf@fomichev.me>, Song Liu <song@kernel.org>,
	syzkaller-bugs <syzkaller-bugs@googlegroups.com>,
	 Yonghong Song <yonghong.song@linux.dev>
Subject: Re: [PATCH v2] bpf: fix NULL pointer dereference in print_reg_state()
Date: Thu, 25 Sep 2025 23:31:41 +0800	[thread overview]
Message-ID: <933a66f3e0e1f642ef53726abe617c4d138a91fa.camel@linux.dev> (raw)
In-Reply-To: <wz6god46aom7lfyuvhju67w47czdznzflec3ilqs6f7fpyf3di@k5wliusgqlut>

On Wed, 2025-09-24 at 23:58 +0530, Brahmajit Das wrote:
> On 25.09.2025 01:38, KaFai Wan wrote:
> > On Wed, 2025-09-24 at 21:10 +0530, Brahmajit Das wrote:
> > > On 24.09.2025 09:32, Alexei Starovoitov wrote:
> > > > On Wed, Sep 24, 2025 at 1:43 AM Brahmajit Das
> > > > <listout@listout.xyz>
> > > > wrote:
> > > > > 
> > > > > Syzkaller reported a general protection fault due to a NULL
> > > > > pointer
> > > > > dereference in print_reg_state() when accessing reg->map_ptr
> > > > > without
> > > > > checking if it is NULL.
> > > > > 
> > > ...snip...
> > > > > -       if (type_is_map_ptr(t)) {
> > > > > +       if (type_is_map_ptr(t) && reg->map_ptr) {
> > > > 
> > > > You ignored earlier feedback.
> > > > Fix the root cause, not the symptom.
> > > > 
> > > > pw-bot: cr
> > > 
> > > I'm not sure if I'm headed the write direction but it seems like
> > > in
> > > check_alu_op, we are calling adjust_scalar_min_max_vals when we
> > > get
> > > an
> > > BPF_NEG as opcode. Which has a call to __mark_reg_known when
> > > opcode
> > > is
> > > BPF_NEG. And __mark_reg_known clears map_ptr with
> > > 
> > > 	/* Clear off and union(map_ptr, range) */
> > > 	memset(((u8 *)reg) + sizeof(reg->type), 0,
> > > 	       offsetof(struct bpf_reg_state, var_off) -
> > > sizeof(reg-
> > > > type));
> > > 
> > 
> > I think you are right. The following code can reproduce the error.
> > 
> > 	asm volatile ("					\
> > 	r0 = %[map_hash_48b] ll;			\
> > 	r0 = -r0;					\
> > 	exit;						\
> > "	:
> > 	: __imm_addr(map_hash_48b)
> > 	: __clobber_all);
> > 
> > 
> > BPF_NEG calls __mark_reg_known(dst_reg, 0) which clears the 'off'
> > and
> > 'union(map_ptr, range)' of dst_reg, but keeps the 'type', which is
> > CONST_PTR_TO_MAP.
> > 
> > Perhaps we can only allow the SCALAR_VALUE type to run BPF_NEG as
> > an
> > opcode, while for other types same as the before BPF_NEG.
> > 
> > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> > index e892df386eed..dbf9f1efc6e7 100644
> > --- a/kernel/bpf/verifier.c
> > +++ b/kernel/bpf/verifier.c
> > @@ -15346,13 +15346,15 @@ static bool
> > is_safe_to_compute_dst_reg_range(struct bpf_insn *insn,
> >  	switch (BPF_OP(insn->code)) {
> >  	case BPF_ADD:
> >  	case BPF_SUB:
> > -	case BPF_NEG:
> >  	case BPF_AND:
> >  	case BPF_XOR:
> >  	case BPF_OR:
> >  	case BPF_MUL:
> >  		return true;
> >  
> > +	case BPF_NEG:
> > +		return base_type(src_reg->type) == SCALAR_VALUE;
> > +
> > 
> > 
> > -- 
> > Thanks,
> > KaFai
> 
> Before even going into adjust_scalar_min_max_vals we have a check in
> check_alu_op, which I think is not being respected. Going to expand
> on
> this below as response to Alexei.
> 
> On 24.09.2025 18:28, Alexei Starovoitov wrote:
> > On Wed, Sep 24, 2025 at 4:41 PM Brahmajit Das <listout@listout.xyz>
> > wrote:
> > > 
> > > On 24.09.2025 09:32, Alexei Starovoitov wrote:
> > > > On Wed, Sep 24, 2025 at 1:43 AM Brahmajit Das
> > > > <listout@listout.xyz> wrote:
> > > > > 
> > > > > Syzkaller reported a general protection fault due to a NULL
> > > > > pointer
> > > > > dereference in print_reg_state() when accessing reg->map_ptr
> > > > > without
> > > > > checking if it is NULL.
> > > > > 
> > > ...snip...
> > > > > -       if (type_is_map_ptr(t)) {
> > > > > +       if (type_is_map_ptr(t) && reg->map_ptr) {
> > > > 
> > > > You ignored earlier feedback.
> > > > Fix the root cause, not the symptom.
> > > > 
> > > > pw-bot: cr
> > > 
> > > I'm not sure if I'm headed the write direction but it seems like
> > > in
> > > check_alu_op, we are calling adjust_scalar_min_max_vals when we
> > > get an
> > > BPF_NEG as opcode. Which has a call to __mark_reg_known when
> > > opcode is
> > > BPF_NEG. And __mark_reg_known clears map_ptr with
> > 
> > Looks like we're getting somewhere.
> > It seems the verifier is not clearing reg->type.
> > adjust_scalar_min_max_vals() should be called on scalar types only.
> 
> Right, there is a check in check_alu_op
> 
> 		if (is_pointer_value(env, insn->dst_reg)) {
> 			verbose(env, "R%d pointer arithmetic
> prohibited\n",
> 				insn->dst_reg);
> 			return -EACCES;
> 		}
> 
> is_pointer_value calls __is_pointer_value which takes bool
> allow_ptr_leaks as the first argument. Now for some reason in this
> case
> allow_ptr_leaks is being passed as true, as a result
> __is_pointer_value
> (and in turn is_pointer_value) returns false when even when register
> type is CONST_PTR_TO_MAP.
> 

IIUC, `env->allow_ptr_leaks` set true means privileged mode (
CAP_PERFMON or CAP_SYS_ADMIN ), false for unprivileged mode. 


We can use __is_pointer_value to check if the register type is a
pointer. For pointers, we check as before (before checking BPF_NEG
separately), and for scalars, it remains unchanged. Perhaps this way we
can fix the error.

if (opcode == BPF_NEG) {
	if (__is_pointer_value(false, &regs[insn->dst_reg])) {
		err = check_reg_arg(env, insn->dst_reg, DST_OP);
	} else {
		err = check_reg_arg(env, insn->dst_reg,
DST_OP_NO_MARK);
		err = err ?: adjust_scalar_min_max_vals(env, insn,
						&regs[insn->dst_reg],
						regs[insn->dst_reg]);
	}
} else {


-- 
Thanks,
KaFai

  reply	other threads:[~2025-09-25 15:32 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-23  9:02 [syzbot] [bpf?] general protection fault in print_reg_state syzbot
2025-09-23 16:41 ` [PATCH 1/1] bpf: fix NULL pointer dereference in print_reg_state() Brahmajit Das
2025-10-01 19:17   ` [PATCH v4 0/2] bpf: Fix verifier crash on BPF_NEG with pointer register Brahmajit Das
2025-10-01 19:17     ` [PATCH v4 1/2] bpf: Skip scalar adjustment for BPF_NEG if dst is a pointer Brahmajit Das
2025-10-01 19:32       ` Eduard Zingerman
2025-10-01 19:17     ` [PATCH v4 2/2] selftests/bpf: Add test for BPF_NEG alu on CONST_PTR_TO_MAP Brahmajit Das
2025-10-01 19:33       ` Eduard Zingerman
2025-10-01 21:10     ` [PATCH v4 0/2] bpf: Fix verifier crash on BPF_NEG with pointer register patchwork-bot+netdevbpf
2025-09-23 16:43 ` [PATCH 1/1] bpf: fix NULL pointer dereference in print_reg_state() Brahmajit Das
2025-09-23 18:52   ` Alexei Starovoitov
2025-09-23 17:10 ` Forwarded: [PATCH] " syzbot
2025-09-23 17:47 ` [PATCH v2] " Brahmajit Das
2025-09-24  7:32   ` Alexei Starovoitov
2025-09-24  9:09     ` Brahmajit Das
2025-09-24 15:40     ` Brahmajit Das
2025-09-24 17:28       ` Alexei Starovoitov
2025-09-24 17:38       ` KaFai Wan
2025-09-24 18:28         ` Brahmajit Das
2025-09-25 15:31           ` KaFai Wan [this message]
2025-09-26  1:04             ` Brahmajit Das
2025-09-26  1:56               ` Brahmajit Das
2025-09-26 10:36               ` KaFai Wan
2025-09-30 18:21                 ` Brahmajit Das
2025-10-01  5:08                   ` KaFai Wan
2025-09-29 18:23 ` [syzbot] [bpf?] general protection fault in print_reg_state syzbot
2025-10-01  9:56 ` [PATCH v3 0/2] bpf: Fix verifier crash on BPF_NEG with pointer register Brahmajit Das
2025-10-01  9:56   ` [PATCH v3 1/2] bpf: Skip scalar adjustment for BPF_NEG if dst is a pointer Brahmajit Das
2025-10-01 16:55     ` Alexei Starovoitov
2025-10-01 18:29     ` Eduard Zingerman
2025-10-01 18:49       ` Brahmajit Das
2025-10-01 18:54         ` Eduard Zingerman
2025-10-01  9:56   ` [PATCH v3 2/2] selftests/bpf: Add test for BPF_NEG alu on CONST_PTR_TO_MAP Brahmajit Das
2025-10-01 18:37     ` Eduard Zingerman
2025-10-01 18:40   ` [PATCH v3 0/2] bpf: Fix verifier crash on BPF_NEG with pointer register Eduard Zingerman
2025-10-01 19:28 ` [PATCH v4 " Brahmajit Das
2025-10-01 19:28   ` [PATCH v4 1/2] bpf: Skip scalar adjustment for BPF_NEG if dst is a pointer Brahmajit Das
2025-10-01 21:10     ` patchwork-bot+netdevbpf
2025-10-01 19:28   ` [PATCH v4 2/2] selftests/bpf: Add test for BPF_NEG alu on CONST_PTR_TO_MAP Brahmajit Das

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=933a66f3e0e1f642ef53726abe617c4d138a91fa.camel@linux.dev \
    --to=kafai.wan@linux.dev \
    --cc=alexei.starovoitov@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=eddyz87@gmail.com \
    --cc=haoluo@google.com \
    --cc=john.fastabend@gmail.com \
    --cc=jolsa@kernel.org \
    --cc=kpsingh@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=listout@listout.xyz \
    --cc=martin.lau@linux.dev \
    --cc=sdf@fomichev.me \
    --cc=song@kernel.org \
    --cc=syzbot+d36d5ae81e1b0a53ef58@syzkaller.appspotmail.com \
    --cc=syzkaller-bugs@googlegroups.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 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.