[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