On Mon, 2026-06-22 at 02:25 +0000, Yiyang Chen wrote:
> bpf_refcount_acquire() increments the refcount at the caller-supplied
> pointer plus the refcount field offset, then returns the caller-supplied
> pointer unchanged.
>
> The verifier records the return value as a base pointer to the refcounted
> object.
>
> bpf_list_pop_front() and bpf_rbtree_remove() can return embedded
> graph-node pointers as PTR_TO_BTF_ID | MEM_ALLOC with a fixed offset equal
> to the node field offset. Passing such a pointer directly to
> bpf_refcount_acquire() currently passes the refcounted-kptr type check.
>
> That makes the runtime operation start from base + node_off while the
> verifier models the returned pointer as the object base.
>
> Require refcount-acquire arguments to have zero fixed offset by carrying
> the requirement through check_func_arg_reg_off() to __check_ptr_off_reg().
> Programs can still acquire a refcount from a graph-node-derived pointer
> after normalizing it with container_of().
>
> Fixes: 7c50b1cb76aca ("bpf: Add bpf_refcount_acquire kfunc")
> Signed-off-by: Yiyang Chen <[email protected]>
> ---
Acked-by: Eduard Zingerman <[email protected]>
This is a bit ugly, but I don't have alternative suggestions.
[...]
> @@ -12135,7 +12146,8 @@ static int check_kfunc_args(struct bpf_verifier_env
> *env, struct bpf_kfunc_call_
>
> if (regno == meta->release_regno)
> arg_type |= OBJ_RELEASE;
> - ret = check_func_arg_reg_off(env, reg, argno, arg_type);
> + ret = __check_func_arg_reg_off(env, reg, argno, arg_type,
> + btf_id_fixed_off_ok);
Nit: line length limit is 100 characters.
> if (ret < 0)
> return ret;
>