Re: [PATCH bpf-next v2 1/2] bpf: Preserve untrusted memory pointer type on scalar add
From: Alexei Starovoitov
Date: Sun Jun 21 2026 - 20:50:51 EST
On Sat, Jun 13, 2026 at 5:38 AM Nuoqi Gui <gnq25@xxxxxxxxxxxxxxxxxxxxx> wrote:
>
> scalar += rdonly_untrusted_mem reaches adjust_ptr_min_max_vals() with the
> pointer as the source register. The untrusted PTR_TO_MEM case returns there
> without updating the scalar destination, leaving stale verifier state.
>
> Handle the untrusted PTR_TO_MEM case before the early return. Addition and
> pointer-minus-scalar subtraction preserve the pointer type and keep the
> existing "do not track offsets" rule for untrusted memory.
> Scalar-minus-pointer and unsupported pointer ALU operations are still
> rejected instead of being accepted by the early return.
>
> Fixes: f2362a57aeff ("bpf: allow void* cast using bpf_rdonly_cast()")
> Signed-off-by: Nuoqi Gui <gnq25@xxxxxxxxxxxxxxxxxxxxx>
> ---
> kernel/bpf/verifier.c | 28 ++++++++++++++++++++++++++--
> 1 file changed, 26 insertions(+), 2 deletions(-)
>
> diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
> index c8d980fdd709..26c67c53166b 100644
> --- a/kernel/bpf/verifier.c
> +++ b/kernel/bpf/verifier.c
> @@ -13729,8 +13729,32 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
> * Accesses to untrusted PTR_TO_MEM are done through probe
> * instructions, hence no need to track offsets.
> */
> - if (base_type(ptr_reg->type) == PTR_TO_MEM && (ptr_reg->type & PTR_UNTRUSTED))
> - return 0;
> + if (base_type(ptr_reg->type) == PTR_TO_MEM &&
> + (ptr_reg->type & PTR_UNTRUSTED)) {
do not introduce line wrap.
> + switch (opcode) {
> + case BPF_ADD:
> + *dst_reg = *ptr_reg;
> + return 0;
> + case BPF_SUB:
> + if (dst_reg == off_reg) {
> + verbose(env, "R%d tried to subtract pointer from scalar\n",
> + dst);
> + return -EACCES;
> + }
> + *dst_reg = *ptr_reg;
> + return 0;
> + case BPF_AND:
> + case BPF_OR:
> + case BPF_XOR:
> + verbose(env, "R%d bitwise operator %s on pointer prohibited\n",
> + dst, bpf_alu_string[opcode >> 4]);
> + return -EACCES;
> + default:
> + verbose(env, "R%d pointer arithmetic with %s operator prohibited\n",
> + dst, bpf_alu_string[opcode >> 4]);
> + return -EACCES;
No need to arbitrary rejection.
All ALUs should be allowed.
Something like
if (ptr_reg != dst_reg)
*dst_reg = *ptr_reg;
pw-bot: cr