[PATCH 25.11] bpf/validate: fix BPF_ADD of pointer to a scalar
Kevin Traynor
ktraynor at redhat.com
Fri Jul 31 12:16:29 CEST 2026
On 7/31/26 10:46, Marat Khalili wrote:
> [ upstream commit 17509d474226fcfa4372498b353238458bf37e2a ]
>
> Function `eval_add` preserved type of the destination register even when
> a pointer was added to it. If it contained scalar, it remained a scalar,
> and if it contained pointer, it remained a pointer.
>
> E.g. consider the following program with the current validation code:
>
> Tested program:
> 0: mov r0, #0x0
> 1: mov r3, #0x0
> 2: add r3, r1 ; tested instruction
> 3: ldxdw r2, [r3 + 16]
> 4: mov r0, #0x1
> 5: exit
>
> After the tested instruction validator considers r3 to be scalar and
> fails validation with the error:
>
> BPF: evaluate(): destination is not a pointer at pc: 3
>
> However, this code is valid as long as program argument points to a
> valid memory area at least 24 bytes long which we read at offset 16.
>
> When adding pointer to a scalar set type of the result to pointer of
> the same type. When adding pointer to a pointer set type of the result
> to scalar and value to unknown.
>
> The test will be added in subsequent commits since it depends on other
> fixes.
>
> Fixes: 8021917293d0 ("bpf: add extra validation for input BPF program")
>
> Signed-off-by: Marat Khalili <marat.khalili at huawei.com>
> Acked-by: Konstantin Ananyev <konstantin.ananyev at huawei.com>
> Signed-off-by: Stephen Hemminger <stephen at networkplumber.org>
> ---
> This backport patch has been modified from the upstream commit to also
> include a pending fix for an uninitialized structure warning caught by
> Coverity. The fix was submitted by Stephen Hemminger (Coverity issue:
> 504611) but has not yet been merged into main. It is included here to
> ensure the backport does not introduce the warning.
>
> lib/bpf/bpf_validate.c | 12 ++++++++++++
> 1 file changed, 12 insertions(+)
>
> diff --git a/lib/bpf/bpf_validate.c b/lib/bpf/bpf_validate.c
> index 64a8f227a3..172915595d 100644
> --- a/lib/bpf/bpf_validate.c
> +++ b/lib/bpf/bpf_validate.c
> @@ -239,8 +239,20 @@ eval_apply_mask(struct bpf_reg_val *rv, uint64_t mask)
> static void
> eval_add(struct bpf_reg_val *rd, const struct bpf_reg_val *rs, uint64_t msk)
> {
> + struct bpf_reg_val rs_buf = { 0 };
> struct bpf_reg_val rv;
>
> + if (RTE_BPF_ARG_PTR_TYPE(rs->v.type) != 0) {
> + if (RTE_BPF_ARG_PTR_TYPE(rd->v.type) != 0) {
> + /* treat sum of pointers as sum of two unknown scalars */
> + eval_fill_max_bound(&rs_buf, msk);
> + *rd = rs_buf;
> + rs = &rs_buf;
> + } else
> + /* scalar + pointer is a pointer of the same type */
> + rd->v = rs->v;
> + }
> +
> rv.u.min = (rd->u.min + rs->u.min) & msk;
> rv.u.max = (rd->u.max + rs->u.max) & msk;
> rv.s.min = ((uint64_t)rd->s.min + (uint64_t)rs->s.min) & msk;
Hi Marat. Got it, thanks. I'll remove previous backport from queue and
add this version.
Kevin.
More information about the stable
mailing list