BPF Archive on lore.kernel.org
 help / color / Atom feed
From: Yonghong Song <yhs@fb.com>
To: John Fastabend <john.fastabend@gmail.com>,
	<alexei.starovoitov@gmail.com>, <daniel@iogearbox.net>
Cc: <bpf@vger.kernel.org>, <kernel-team@fb.com>
Subject: Re: [bpf PATCH 1/3] bpf: fix a verifier issue when assigning 32bit reg states to 64bit ones
Date: Fri, 29 May 2020 11:40:35 -0700
Message-ID: <a5a68612-f023-3dc3-7fa9-a8b46d7b8f12@fb.com> (raw)
In-Reply-To: <159077331983.6014.5758956193749002737.stgit@john-Precision-5820-Tower>



On 5/29/20 10:28 AM, John Fastabend wrote:
> With the latest trunk llvm (llvm 11), I hit a verifier issue for
> test_prog subtest test_verif_scale1.
> 
> The following simplified example illustrate the issue:
>      w9 = 0  /* R9_w=inv0 */
>      r8 = *(u32 *)(r1 + 80)  /* __sk_buff->data_end */
>      r7 = *(u32 *)(r1 + 76)  /* __sk_buff->data */
>      ......
>      w2 = w9 /* R2_w=inv0 */
>      r6 = r7 /* R6_w=pkt(id=0,off=0,r=0,imm=0) */
>      r6 += r2 /* R6_w=inv(id=0) */
>      r3 = r6 /* R3_w=inv(id=0) */
>      r3 += 14 /* R3_w=inv(id=0) */
>      if r3 > r8 goto end
>      r5 = *(u32 *)(r6 + 0) /* R6_w=inv(id=0) */
>         <== error here: R6 invalid mem access 'inv'
>      ...
>    end:
> 
> In real test_verif_scale1 code, "w9 = 0" and "w2 = w9" are in
> different basic blocks.
> 
> In the above, after "r6 += r2", r6 becomes a scalar, which eventually
> caused the memory access error. The correct register state should be
> a pkt pointer.
> 
> The inprecise register state starts at "w2 = w9".
> The 32bit register w9 is 0, in __reg_assign_32_into_64(),
> the 64bit reg->smax_value is assigned to be U32_MAX.
> The 64bit reg->smin_value is 0 and the 64bit register
> itself remains constant based on reg->var_off.
> 
> In adjust_ptr_min_max_vals(), the verifier checks for a known constant,
> smin_val must be equal to smax_val. Since they are not equal,
> the verifier decides r6 is a unknown scalar, which caused later failure.
> 
> The llvm10 does not have this issue as it generates different code:
>      w9 = 0  /* R9_w=inv0 */
>      r8 = *(u32 *)(r1 + 80)  /* __sk_buff->data_end */
>      r7 = *(u32 *)(r1 + 76)  /* __sk_buff->data */
>      ......
>      r6 = r7 /* R6_w=pkt(id=0,off=0,r=0,imm=0) */
>      r6 += r9 /* R6_w=pkt(id=0,off=0,r=0,imm=0) */
>      r3 = r6 /* R3_w=pkt(id=0,off=0,r=0,imm=0) */
>      r3 += 14 /* R3_w=pkt(id=0,off=14,r=0,imm=0) */
>      if r3 > r8 goto end
>      ...
> 
> To fix the above issue, we can include zero in the test condition for
> assigning the s32_max_value and s32_min_value to their 64-bit equivalents
> smax_value and smin_value.
> 
> Further, fix the condition to avoid doing zero extension bounds checks
> when s32_min_value <= 0. This could allow for the case where bounds
> 32-bit bounds (-1,1) get incorrectly translated to (0,1) 64-bit bounds.
> When in-fact the -1 min value needs to force U32_MAX bound.
> 
> Fixes: 3f50f132d840 ("bpf: Verifier, do explicit ALU32 bounds tracking")
> Signed-off-by: John Fastabend <john.fastabend@gmail.com>
> ---
>   kernel/bpf/verifier.c |   10 +++++-----
>   1 file changed, 5 insertions(+), 5 deletions(-)

Thanks for the fix. LGTM.
Acked-by: Yonghong Song <yhs@fb.com>

  reply index

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-29 17:28 [bpf PATCH 0/3] verifier fix for assigning 32bit reg to 64bit reg John Fastabend
2020-05-29 17:28 ` [bpf PATCH 1/3] bpf: fix a verifier issue when assigning 32bit reg states to 64bit ones John Fastabend
2020-05-29 18:40   ` Yonghong Song [this message]
2020-05-29 17:28 ` [bpf PATCH 2/3] bpf, selftests: verifier bounds tests need to be updated John Fastabend
2020-05-29 18:41   ` Yonghong Song
2020-05-29 17:29 ` [bpf PATCH 3/3] bpf, selftests: add a verifier test for assigning 32bit reg states to 64bit ones John Fastabend
2020-05-29 20:53 ` [bpf PATCH 0/3] verifier fix for assigning 32bit reg to 64bit reg Alexei Starovoitov

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=a5a68612-f023-3dc3-7fa9-a8b46d7b8f12@fb.com \
    --to=yhs@fb.com \
    --cc=alexei.starovoitov@gmail.com \
    --cc=bpf@vger.kernel.org \
    --cc=daniel@iogearbox.net \
    --cc=john.fastabend@gmail.com \
    --cc=kernel-team@fb.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

BPF Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/bpf/0 bpf/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 bpf bpf/ https://lore.kernel.org/bpf \
		bpf@vger.kernel.org
	public-inbox-index bpf

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.bpf


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git