From: Marat Khalili <marat.khalili@huawei.com>
To: Konstantin Ananyev <konstantin.ananyev@huawei.com>
Cc: <dev@dpdk.org>, <stable@dpdk.org>
Subject: [PATCH 21/25] bpf/validate: fix BPF_SUB signed max zero case
Date: Wed, 6 May 2026 18:38:39 +0100 [thread overview]
Message-ID: <20260506173846.64914-22-marat.khalili@huawei.com> (raw)
In-Reply-To: <20260506173846.64914-1-marat.khalili@huawei.com>
Function `eval_sub` used source register signed minimum to detect
overflow of the difference (operation result) signed minimum, and source
register signed maximum to detect overflow of the difference signed
maximum. However in the actual formula for difference source register
bounds are swapped (correctly, since we subtract it), so in overflow
detection we should also have swapped them. It caused false negatives in
certain cases.
E.g. consider the following program with the current validation code:
Tested program:
0: mov r0, #0x0
1: ldxdw r2, [r1 + 0]
2: jsgt r2, #0x0, L7
3: ldxdw r3, [r1 + 8]
4: jsgt r3, #0x0, L7
5: sub r2, r3 ; tested instruction
6: mov r0, #0x1
7: exit
Pre-state:
r2: INT64_MIN..0
r3: INT64_MIN..0
Post-state:
r2: INT64_MIN
Validator ignores overflow of signed minimum and considers result to
always equal INT64_MIN. However, if -1 was loaded on step 1 and -2 was
loaded on step 3 it is possible for the difference to equal 1.
Swap source register signed minimum and maximum in the overflow
condition to match the new range formula, add test.
Fixes: 8021917293d0 ("bpf: add extra validation for input BPF program")
Cc: stable@dpdk.org
Signed-off-by: Marat Khalili <marat.khalili@huawei.com>
---
app/test/test_bpf_validate.c | 17 +++++++++++++++++
lib/bpf/bpf_validate.c | 4 ++--
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/app/test/test_bpf_validate.c b/app/test/test_bpf_validate.c
index 9d3e48b5f93c..44e08062b3ee 100644
--- a/app/test/test_bpf_validate.c
+++ b/app/test/test_bpf_validate.c
@@ -1747,6 +1747,23 @@ test_alu64_or_k_positive(void)
REGISTER_FAST_TEST(bpf_validate_alu64_or_k_positive_autotest, NOHUGE_OK, ASAN_OK,
test_alu64_or_k_positive);
+/* 64-bit difference between two negative ranges.. */
+static int
+test_alu64_sub_x_src_signed_max_zero(void)
+{
+ return verify_instruction((struct verify_instruction_param){
+ .tested_instruction = {
+ .code = (EBPF_ALU64 | BPF_SUB | BPF_X),
+ },
+ .pre.dst = make_signed_domain(INT64_MIN, 0),
+ .pre.src = make_signed_domain(INT64_MIN, 0),
+ .post.dst = unknown,
+ });
+}
+
+REGISTER_FAST_TEST(bpf_validate_alu64_sub_x_src_signed_max_zero_autotest, NOHUGE_OK, ASAN_OK,
+ test_alu64_sub_x_src_signed_max_zero);
+
/* Jump if greater than immediate. */
static int
test_jmp64_jeq_k(void)
diff --git a/lib/bpf/bpf_validate.c b/lib/bpf/bpf_validate.c
index d9ee0563c9d3..a500ad662c1b 100644
--- a/lib/bpf/bpf_validate.c
+++ b/lib/bpf/bpf_validate.c
@@ -716,9 +716,9 @@ eval_sub(struct bpf_reg_val *rd, const struct bpf_reg_val *rs, uint64_t msk)
eval_umax_bound(&rv, msk);
if ((rd->s.min != rd->s.max || rs->s.min != rs->s.max) &&
- (((rs->s.min < 0 && rv.s.min < rd->s.min) ||
+ (((rs->s.max < 0 && rv.s.min < rd->s.min) ||
rv.s.min > rd->s.min) ||
- ((rs->s.max < 0 && rv.s.max < rd->s.max) ||
+ ((rs->s.min < 0 && rv.s.max < rd->s.max) ||
rv.s.max > rd->s.max)))
eval_smax_bound(&rv, msk);
--
2.43.0
next prev parent reply other threads:[~2026-05-06 17:41 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-06 17:38 [PATCH 00/25] bpf: test and fix issues in verifier Marat Khalili
2026-05-06 17:38 ` [PATCH 01/25] bpf: format and dump jlt, jle, jslt, and jsle Marat Khalili
2026-05-06 17:38 ` [PATCH 02/25] bpf: add format instruction function Marat Khalili
2026-05-06 17:38 ` [PATCH 03/25] bpf/validate: break on error in evaluate Marat Khalili
2026-05-06 17:38 ` [PATCH 04/25] bpf/validate: expand comments in evaluate cycle Marat Khalili
2026-05-06 17:38 ` [PATCH 05/25] bpf/validate: introduce debugging interface Marat Khalili
2026-05-06 17:38 ` [PATCH 06/25] bpf/validate: fix BPF_ADD of pointer to a scalar Marat Khalili
2026-05-06 17:38 ` [PATCH 07/25] bpf/validate: fix BPF_LDX | EBPF_DW signed range Marat Khalili
2026-05-06 17:38 ` [PATCH 08/25] test/bpf_validate: add setup and basic tests Marat Khalili
2026-05-06 17:38 ` [PATCH 09/25] test/bpf_validate: add harness for pointer tests Marat Khalili
2026-05-06 17:38 ` [PATCH 10/25] bpf/validate: fix EBPF_JSLT | BPF_X evaluation Marat Khalili
2026-05-06 17:38 ` [PATCH 11/25] bpf/validate: fix BPF_NEG of INT64_MIN and 0 Marat Khalili
2026-05-06 17:38 ` [PATCH 12/25] bpf/validate: fix BPF_DIV and BPF_MOD signed part Marat Khalili
2026-05-06 17:38 ` [PATCH 13/25] bpf/validate: fix BPF_MUL ranges minimum typo Marat Khalili
2026-05-06 17:38 ` [PATCH 14/25] bpf/validate: fix BPF_MUL signed overflow UB Marat Khalili
2026-05-06 17:38 ` [PATCH 15/25] bpf/validate: fix BPF_JGT/EBPF_JSGT no-jump max Marat Khalili
2026-05-06 17:38 ` [PATCH 16/25] bpf/validate: fix BPF_JMP source range calculation Marat Khalili
2026-05-06 17:38 ` [PATCH 17/25] bpf/validate: fix BPF_JMP empty range handling Marat Khalili
2026-05-06 17:38 ` [PATCH 18/25] bpf/validate: fix BPF_AND min calculations Marat Khalili
2026-05-06 17:38 ` [PATCH 19/25] bpf/validate: fix BPF_LSH shift-out-of-bounds UB Marat Khalili
2026-05-06 17:38 ` [PATCH 20/25] bpf/validate: fix BPF_OR min calculations Marat Khalili
2026-05-06 17:38 ` Marat Khalili [this message]
2026-05-06 17:38 ` [PATCH 22/25] bpf/validate: fix BPF_XOR signed min calculation Marat Khalili
2026-05-06 17:38 ` [PATCH 23/25] bpf/validate: prevent overflow when building graph Marat Khalili
2026-05-06 17:38 ` [PATCH 24/25] doc: add release notes for BPF validation fixes Marat Khalili
2026-05-06 17:38 ` [PATCH 25/25] doc: add BPF validate debug to programmer's guide Marat Khalili
2026-05-08 17:41 ` Stephen Hemminger
2026-05-09 12:36 ` [PATCH 00/25] bpf: test and fix issues in verifier Konstantin Ananyev
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=20260506173846.64914-22-marat.khalili@huawei.com \
--to=marat.khalili@huawei.com \
--cc=dev@dpdk.org \
--cc=konstantin.ananyev@huawei.com \
--cc=stable@dpdk.org \
/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