public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Eduard Zingerman <eddyz87@gmail.com>
To: Andrii Nakryiko <andrii.nakryiko@gmail.com>
Cc: Hao Sun <sunhao.th@gmail.com>,
	Alexei Starovoitov <ast@kernel.org>,
	 Andrii Nakryiko <andrii@kernel.org>,
	Daniel Borkmann <daniel@iogearbox.net>, bpf <bpf@vger.kernel.org>,
	Linux Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: [Bug Report] bpf: incorrectly pruning runtime execution path
Date: Fri, 15 Dec 2023 03:24:42 +0200	[thread overview]
Message-ID: <2b49b96de9f8a1cd6d78cc5aebe7c35776cd2c19.camel@gmail.com> (raw)
In-Reply-To: <526d4ac8f6788d3323d29fdbad0e0e5d09a534db.camel@gmail.com>

On Fri, 2023-12-15 at 02:49 +0200, Eduard Zingerman wrote:
> On Thu, 2023-12-14 at 16:06 -0800, Andrii Nakryiko wrote:
> [...]
> > If you agree with the analysis, we can start discussing what's the
> > best way to fix this.
> 
> Ok, yeap, I agree with you. 
> Backtracker marks both registers in 'if' statement if one of them is
> tracked, but r8 is not marked at block entry and we miss r0.

The brute-force solution is to keep a special mask for each
conditional jump in jump history. In this mask, mark all registers and
stack slots that gained range because of find_equal_scalars() executed
for this conditional jump. Use this mask to extend precise registers set.
However, such mask would be prohibitively large: (10+64)*8 bits.

---

Here is an option that would fix the test in question, but I'm not
sure if it covers all cases:
1. At the last instruction of each state (first instruction to be
   backtracked) we know the set of IDs that should be tracked for
   precision, as currently marked by mark_precise_scalar_ids().
2. In jump history we can record IDs for src and dst registers when new
   entry is pushed.
3. While backtracking 'if' statement, if one of the recorded IDs is in
   the set identified at (1), add src/dst regs to precise registers set.

E.g. for the test-case at hand:

  0: (85) call bpf_get_prandom_u32#7    ; R0=scalar()
  1: (bf) r7 = r0                       ; R0=scalar(id=1) R7_w=scalar(id=1)
  2: (bf) r8 = r0                       ; R0=scalar(id=1) R8_w=scalar(id=1)
  3: (85) call bpf_get_prandom_u32#7    ; R0=scalar()
  --- checkpoint #1 r7.id = 1, r8.id = 1 ---
  4: (25) if r0 > 0x1 goto pc+0         ; R0=scalar(smin=smin32=0,smax=umax=smax32=umax32=1,...)
  --- checkpoint #2 r7.id = 1, r8.id = 1 ---
  5: (3d) if r8 >= r0 goto pc+3         ; R0=1 R8=0 | record r8.id=1 in jump history
  6: (0f) r8 += r8                      ; R8=0
  --- checkpoint #3 r7.id = 1, r8.id = 0 ---
  7: (15) if r7 == 0x0 goto pc+1

The precise set for checkpoint #3 state is {1}.
When insn (5) is backtracked r8.id would be in jump history and in
"precise set" => r8 and r0 would be added to backtracker state.

But this seems a bit ad-hoc.

  reply	other threads:[~2023-12-15  1:24 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-11 15:31 [Bug Report] bpf: incorrectly pruning runtime execution path Hao Sun
2023-12-13  0:51 ` Andrii Nakryiko
2023-12-13 10:25   ` Hao Sun
2023-12-13 23:30     ` Andrii Nakryiko
2023-12-14  0:08       ` Eduard Zingerman
2023-12-14  0:36         ` Andrii Nakryiko
2023-12-13 23:35     ` Eduard Zingerman
2023-12-13 23:40       ` Andrii Nakryiko
2023-12-13 23:47         ` Eduard Zingerman
2023-12-13 23:50           ` Andrii Nakryiko
2023-12-14  9:38       ` Hao Sun
2023-12-14 15:10         ` Eduard Zingerman
2023-12-14 16:26           ` Eduard Zingerman
2023-12-15  0:06             ` Andrii Nakryiko
2023-12-15  0:16               ` Eduard Zingerman
2023-12-15  0:49               ` Eduard Zingerman
2023-12-15  1:24                 ` Eduard Zingerman [this message]
2023-12-15  1:43                   ` Eduard Zingerman
2023-12-15  2:16                   ` Alexei Starovoitov
2023-12-15  2:28                     ` Eduard Zingerman
2023-12-15  5:20                       ` Andrii Nakryiko
2023-12-15 16:22                         ` Eduard Zingerman
2023-12-15 17:01                           ` Andrii Nakryiko
2023-12-15 20:55                     ` 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=2b49b96de9f8a1cd6d78cc5aebe7c35776cd2c19.camel@gmail.com \
    --to=eddyz87@gmail.com \
    --cc=andrii.nakryiko@gmail.com \
    --cc=andrii@kernel.org \
    --cc=ast@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sunhao.th@gmail.com \
    /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