* [PATCH bpf v2 0/2] bpf: Fix refcount_acquire handling for borrowed kptrs @ 2026-07-26 23:50 Ning Ding 2026-07-26 23:50 ` [PATCH bpf v2 1/2] bpf: Keep refcount_acquire nullable for borrowed RCU kptrs Ning Ding 2026-07-26 23:50 ` [PATCH bpf v2 2/2] bpf: Reject untrusted pointers in refcount_acquire Ning Ding 0 siblings, 2 replies; 7+ messages in thread From: Ning Ding @ 2026-07-26 23:50 UTC (permalink / raw) To: bpf; +Cc: ast, daniel, andrii, eddyz87, memxor, martin.lau, davem, greg This series fixes two bugs in bpf_refcount_acquire() verifier handling. Patch 1 fixes return-value tracking. The verifier can treat an RCU-loaded borrowed map kptr as owning and mark the return value non-NULL. At runtime, bpf_refcount_acquire() can still return NULL, allowing an unchecked NULL value to reach bpf_obj_drop() and crash the kernel. Patch 2 fixes argument validation. After bpf_rcu_read_unlock(), the pointer is PTR_UNTRUSTED, but the verifier still allows it to be passed to bpf_refcount_acquire(). A reproducer with only CAP_BPF acquired a reference through this stale pointer after the original object was dropped and its address was reused. The series adds verifier regression tests for both cases. Changes since v1: - Patch 1 is unchanged. - Added Patch 2 to reject PTR_UNTRUSTED refcounted kptr inputs after bpf_rcu_read_unlock(). - Reused the refcount-only selftest fixture introduced by Patch 1. - Added fail-before/pass-after verifier validation and CAP_BPF-only runtime confirmation. Link: https://lore.kernel.org/r/20260726015330.705259-1-dingning04@gmail.com Ning Ding (2): bpf: Keep refcount_acquire nullable for borrowed RCU kptrs bpf: Reject untrusted pointers in refcount_acquire kernel/bpf/verifier.c | 7 +- .../selftests/bpf/progs/refcounted_kptr.c | 61 +++++++++++++++ .../bpf/progs/refcounted_kptr_fail.c | 74 +++++++++++++++++++ 3 files changed, 141 insertions(+), 1 deletion(-) -- 2.43.0 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH bpf v2 1/2] bpf: Keep refcount_acquire nullable for borrowed RCU kptrs 2026-07-26 23:50 [PATCH bpf v2 0/2] bpf: Fix refcount_acquire handling for borrowed kptrs Ning Ding @ 2026-07-26 23:50 ` Ning Ding 2026-07-27 4:50 ` Greg KH 2026-07-26 23:50 ` [PATCH bpf v2 2/2] bpf: Reject untrusted pointers in refcount_acquire Ning Ding 1 sibling, 1 reply; 7+ messages in thread From: Ning Ding @ 2026-07-26 23:50 UTC (permalink / raw) To: bpf; +Cc: ast, daniel, andrii, eddyz87, memxor, martin.lau, davem, greg bpf_refcount_acquire() returns NULL if the object's refcount has reached zero. For an RCU-loaded map kptr, another thread can replace the map entry and drop the last owning reference before the acquire, which makes the ref count drop to 0. However, the verifier incorrectly marks the input as owning solely because it lacks NON_OWN_REF, and therefore treats the return value as non-NULL. This allows an unchecked NULL return to be passed to bpf_obj_drop(), which can crash the kernel. Only treat the input as owning when it is present in the verifier's acquired-reference state. Add tests for owning input, checked borrowed RCU input, and unchecked borrowed RCU input. Fixes: 7793fc3babe9 ("bpf: Make bpf_refcount_acquire fallible for non-owning refs") Assisted-by: Codex:gpt-5.5 Assisted-by: ChatGPT:GPT-5.6-Thinking Signed-off-by: Ning Ding <dingning04@gmail.com> --- kernel/bpf/verifier.c | 2 +- .../selftests/bpf/progs/refcounted_kptr.c | 61 +++++++++++++++++++ .../bpf/progs/refcounted_kptr_fail.c | 47 ++++++++++++++ 3 files changed, 109 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 7aa47342dc65..1e7343b625de 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -12419,7 +12419,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_ reg_arg_name(env, argno)); return -EINVAL; } - if (!type_is_non_owning_ref(reg->type)) + if (!type_is_non_owning_ref(reg->type) && reg_is_referenced(env, reg)) meta->arg_owning_ref = true; rec = reg_btf_record(reg); diff --git a/tools/testing/selftests/bpf/progs/refcounted_kptr.c b/tools/testing/selftests/bpf/progs/refcounted_kptr.c index 61906f48025c..fd35093285c0 100644 --- a/tools/testing/selftests/bpf/progs/refcounted_kptr.c +++ b/tools/testing/selftests/bpf/progs/refcounted_kptr.c @@ -23,6 +23,15 @@ struct map_value { struct node_data __kptr *node; }; +struct node_refcount_only { + long key; + struct bpf_refcount refcount; +}; + +struct map_value_refcount_only { + struct node_refcount_only __kptr *node; +}; + struct { __uint(type, BPF_MAP_TYPE_ARRAY); __type(key, int); @@ -30,6 +39,13 @@ struct { __uint(max_entries, 2); } stashed_nodes SEC(".maps"); +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __type(key, int); + __type(value, struct map_value_refcount_only); + __uint(max_entries, 1); +} stashed_refcount_only SEC(".maps"); + struct node_acquire { long key; long data; @@ -832,6 +848,51 @@ long rbtree_refcounted_node_ref_escapes_owning_input(void *ctx) return 0; } +SEC("tc") +__success +long refcount_acquire_owning_input_no_null_check(void *ctx) +{ + struct node_refcount_only *n, *m; + + n = bpf_obj_new(typeof(*n)); + if (!n) + return 1; + + m = bpf_refcount_acquire(n); + bpf_obj_drop(m); + bpf_obj_drop(n); + + return 0; +} + +SEC("tc") +__success +long refcount_acquire_rcu_map_kptr_null_checked(void *ctx) +{ + struct map_value_refcount_only *mapval; + struct node_refcount_only *n, *m; + int idx = 0; + + mapval = bpf_map_lookup_elem(&stashed_refcount_only, &idx); + if (!mapval) + return 1; + + bpf_rcu_read_lock(); + n = mapval->node; + if (!n) { + bpf_rcu_read_unlock(); + return 2; + } + m = bpf_refcount_acquire(n); + bpf_rcu_read_unlock(); + + if (!m) + return 3; + bpf_obj_drop(m); + + return 0; +} + static long __stash_map_empty_xchg(struct node_data *n, int idx) { struct map_value *mapval = bpf_map_lookup_elem(&stashed_nodes, &idx); diff --git a/tools/testing/selftests/bpf/progs/refcounted_kptr_fail.c b/tools/testing/selftests/bpf/progs/refcounted_kptr_fail.c index 024ef2aae200..acd3e81a3916 100644 --- a/tools/testing/selftests/bpf/progs/refcounted_kptr_fail.c +++ b/tools/testing/selftests/bpf/progs/refcounted_kptr_fail.c @@ -19,6 +19,15 @@ struct node_refcounted { struct bpf_refcount refcount; }; +struct node_refcount_only { + long key; + struct bpf_refcount refcount; +}; + +struct map_value_refcount_only { + struct node_refcount_only __kptr *node; +}; + extern void bpf_rcu_read_lock(void) __ksym; extern void bpf_rcu_read_unlock(void) __ksym; @@ -28,6 +37,13 @@ private(A) struct bpf_rb_root groot __contains(node_acquire, node); private(B) struct bpf_spin_lock lock; private(B) struct bpf_list_head head __contains(node_refcounted, list); +struct { + __uint(type, BPF_MAP_TYPE_ARRAY); + __type(key, int); + __type(value, struct map_value_refcount_only); + __uint(max_entries, 1); +} stashed_refcount_only SEC(".maps"); + static bool less(struct bpf_rb_node *a, const struct bpf_rb_node *b) { struct node_acquire *node_a; @@ -80,6 +96,37 @@ long refcount_acquire_maybe_null(void *ctx) return 0; } +SEC("?tc") +__failure __msg("Possibly NULL pointer passed to trusted R1") +long refcount_acquire_rcu_map_kptr_unchecked_drop(void *ctx) +{ + struct map_value_refcount_only *mapval; + struct node_refcount_only *tmp, *n, *m; + int idx = 0; + + tmp = bpf_obj_new(typeof(*tmp)); + if (!tmp) + return 3; + bpf_obj_drop(tmp); + + mapval = bpf_map_lookup_elem(&stashed_refcount_only, &idx); + if (!mapval) + return 1; + + bpf_rcu_read_lock(); + n = mapval->node; + if (!n) { + bpf_rcu_read_unlock(); + return 2; + } + m = bpf_refcount_acquire(n); + bpf_rcu_read_unlock(); + + bpf_obj_drop(m); + + return 0; +} + SEC("?tc") __failure __msg("Unreleased reference id=3 alloc_insn={{[0-9]+}}") long rbtree_refcounted_node_ref_escapes_owning_input(void *ctx) -- 2.43.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH bpf v2 1/2] bpf: Keep refcount_acquire nullable for borrowed RCU kptrs 2026-07-26 23:50 ` [PATCH bpf v2 1/2] bpf: Keep refcount_acquire nullable for borrowed RCU kptrs Ning Ding @ 2026-07-27 4:50 ` Greg KH 0 siblings, 0 replies; 7+ messages in thread From: Greg KH @ 2026-07-27 4:50 UTC (permalink / raw) To: Ning Ding; +Cc: bpf, ast, daniel, andrii, eddyz87, memxor, martin.lau, davem On Sun, Jul 26, 2026 at 04:50:29PM -0700, Ning Ding wrote: > bpf_refcount_acquire() returns NULL if the object's refcount has > reached zero. For an RCU-loaded map kptr, another thread can replace > the map entry and drop the last owning reference before the acquire, > which makes the ref count drop to 0. > > However, the verifier incorrectly marks the input as owning solely because it > lacks NON_OWN_REF, and therefore treats the return value as non-NULL. > This allows an unchecked NULL return to be passed to bpf_obj_drop(), > which can crash the kernel. > > Only treat the input as owning when it is present in the verifier's > acquired-reference state. Add tests for owning input, checked borrowed > RCU input, and unchecked borrowed RCU input. > > Fixes: 7793fc3babe9 ("bpf: Make bpf_refcount_acquire fallible for non-owning refs") > Assisted-by: Codex:gpt-5.5 > Assisted-by: ChatGPT:GPT-5.6-Thinking > Signed-off-by: Ning Ding <dingning04@gmail.com> > --- > kernel/bpf/verifier.c | 2 +- > .../selftests/bpf/progs/refcounted_kptr.c | 61 +++++++++++++++++++ > .../bpf/progs/refcounted_kptr_fail.c | 47 ++++++++++++++ > 3 files changed, 109 insertions(+), 1 deletion(-) > Hi, This is the friendly patch-bot of Greg Kroah-Hartman. You have sent him a patch that has triggered this response. He used to manually respond to these common problems, but in order to save his sanity (he kept writing the same thing over and over, yet to different people), I was created. Hopefully you will not take offence and will fix the problem in your patch and resubmit it so that it can be accepted into the Linux kernel tree. You are receiving this message because of the following common error(s) as indicated below: - You have marked a patch with a "Fixes:" tag for a commit that is in an older released kernel, yet you do not have a cc: stable line in the signed-off-by area at all, which means that the patch will not be applied to any older kernel releases. To properly fix this, please follow the documented rules in the Documentation/process/stable-kernel-rules.rst file for how to resolve this. If you wish to discuss this problem further, or you have questions about how to resolve this issue, please feel free to respond to this email and Greg will reply once he has dug out from the pending patches received from other developers. thanks, greg k-h's patch email bot ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH bpf v2 2/2] bpf: Reject untrusted pointers in refcount_acquire 2026-07-26 23:50 [PATCH bpf v2 0/2] bpf: Fix refcount_acquire handling for borrowed kptrs Ning Ding 2026-07-26 23:50 ` [PATCH bpf v2 1/2] bpf: Keep refcount_acquire nullable for borrowed RCU kptrs Ning Ding @ 2026-07-26 23:50 ` Ning Ding 2026-07-27 0:13 ` sashiko-bot 2026-07-27 4:50 ` Greg KH 1 sibling, 2 replies; 7+ messages in thread From: Ning Ding @ 2026-07-26 23:50 UTC (permalink / raw) To: bpf; +Cc: ast, daniel, andrii, eddyz87, memxor, martin.lau, davem, greg After bpf_rcu_read_unlock(), a refcounted map kptr is marked PTR_UNTRUSTED because it is no longer protected by RCU. The refcounted-kptr argument check ignores PTR_UNTRUSTED and still allows bpf_refcount_acquire() on that pointer. However, if another thread removes the object and drops its last reference, the stale address can later be reused for another refcounted object. A CAP_BPF-only reproducer observed bpf_refcount_acquire() returning non-NULL through such a stale pointer. Reject PTR_UNTRUSTED refcounted-kptr arguments and add a regression test. Fixes: 7c50b1cb76ac ("bpf: Add bpf_refcount_acquire kfunc") Reported-by: sashiko-bot@kernel.org Link: https://lore.kernel.org/r/20260726021304.97ED91F000E9@smtp.kernel.org Assisted-by: Codex:gpt-5 Signed-off-by: Ning Ding <dingning04@gmail.com> --- kernel/bpf/verifier.c | 5 ++++ .../bpf/progs/refcounted_kptr_fail.c | 27 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 1e7343b625de..63b1d997fe80 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -12414,6 +12414,11 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_ meta->subprogno = reg->subprogno; break; case KF_ARG_PTR_TO_REFCOUNTED_KPTR: + if (reg->type & PTR_UNTRUSTED) { + verbose(env, "%s is an untrusted refcounted kptr\n", + reg_arg_name(env, argno)); + return -EACCES; + } if (!type_is_ptr_alloc_obj(reg->type)) { verbose(env, "%s is neither owning or non-owning ref\n", reg_arg_name(env, argno)); diff --git a/tools/testing/selftests/bpf/progs/refcounted_kptr_fail.c b/tools/testing/selftests/bpf/progs/refcounted_kptr_fail.c index acd3e81a3916..80b92d7ec9ca 100644 --- a/tools/testing/selftests/bpf/progs/refcounted_kptr_fail.c +++ b/tools/testing/selftests/bpf/progs/refcounted_kptr_fail.c @@ -127,6 +127,33 @@ long refcount_acquire_rcu_map_kptr_unchecked_drop(void *ctx) return 0; } +SEC("?tc") +__failure __msg("is an untrusted refcounted kptr") +long refcount_acquire_after_rcu_unlock(void *ctx) +{ + struct map_value_refcount_only *mapval; + struct node_refcount_only *n, *m; + int idx = 0; + + mapval = bpf_map_lookup_elem(&stashed_refcount_only, &idx); + if (!mapval) + return 1; + + bpf_rcu_read_lock(); + n = mapval->node; + if (!n) { + bpf_rcu_read_unlock(); + return 2; + } + bpf_rcu_read_unlock(); + + m = bpf_refcount_acquire(n); + if (m) + bpf_obj_drop(m); + + return 0; +} + SEC("?tc") __failure __msg("Unreleased reference id=3 alloc_insn={{[0-9]+}}") long rbtree_refcounted_node_ref_escapes_owning_input(void *ctx) -- 2.43.0 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH bpf v2 2/2] bpf: Reject untrusted pointers in refcount_acquire 2026-07-26 23:50 ` [PATCH bpf v2 2/2] bpf: Reject untrusted pointers in refcount_acquire Ning Ding @ 2026-07-27 0:13 ` sashiko-bot 2026-07-27 0:40 ` Ning Ding 2026-07-27 4:50 ` Greg KH 1 sibling, 1 reply; 7+ messages in thread From: sashiko-bot @ 2026-07-27 0:13 UTC (permalink / raw) To: Ning Ding; +Cc: bpf Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: Pre-existing issues: - [Critical] check_ptr_to_btf_access() incorrectly allows writes to PTR_UNTRUSTED allocated objects or triggers a verifier_bug WARN_ONCE when reading from them. -- --- Patch [2]: [PATCH bpf v2 2/2] bpf: Reject untrusted pointers in refcount_acquire --- commit 80e6c61503b2eee2d4804b0a7ec8927827ed7d92 Author: Ning Ding <dingning04@gmail.com> bpf: Reject untrusted pointers in refcount_acquire This commit fixes an issue where a refcounted map kptr could still be passed to bpf_refcount_acquire() after being marked PTR_UNTRUSTED due to bpf_rcu_read_unlock(). It updates check_kfunc_args() to reject PTR_UNTRUSTED arguments for KF_ARG_PTR_TO_REFCOUNTED_KPTR. Link: https://lore.kernel.org/r/20260726021304.97ED91F000E9@smtp.kernel.org > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c > index 1e7343b625de5..63b1d997fe804 100644 > --- a/kernel/bpf/verifier.c > +++ b/kernel/bpf/verifier.c > @@ -12414,6 +12414,11 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_ > meta->subprogno = reg->subprogno; > break; > case KF_ARG_PTR_TO_REFCOUNTED_KPTR: > + if (reg->type & PTR_UNTRUSTED) { > + verbose(env, "%s is an untrusted refcounted kptr\n", > + reg_arg_name(env, argno)); > + return -EACCES; > + } [Severity: Critical] This is a pre-existing issue, but I noticed a similar problem with PTR_UNTRUSTED handling in check_ptr_to_btf_access() for allocated objects: kernel/bpf/verifier.c:check_ptr_to_btf_access() { ... if (atype != BPF_READ && !type_is_ptr_alloc_obj(reg->type)) { verbose(env, "only read is supported\n"); return -EACCES; } if (type_is_alloc(reg->type) && !type_is_non_owning_ref(reg->type) && !(reg->type & MEM_RCU) && !reg_is_referenced(env, reg)) { verifier_bug(env, "allocated object must have a referenced id"); return -EFAULT; } ... } Does this logic incorrectly allow writes to PTR_UNTRUSTED allocated objects or trigger a verifier_bug WARN_ONCE when reading from them? If a program loads a program-allocated kptr containing an RCU-protected field inside bpf_rcu_read_lock(), the verifier marks it MEM_ALLOC | MEM_RCU (and NON_OWN_REF if it contains a bpf_rb_node or bpf_list_node). When the program calls bpf_rcu_read_unlock(), it strips MEM_RCU and adds PTR_UNTRUSTED. If the program subsequently tries to read or write this pointer, type_is_ptr_alloc_obj(reg->type) evaluates to true because it ignores PTR_UNTRUSTED, bypassing the read-only check for writes. Then, if the pointer lacks NON_OWN_REF, it hits the type_is_alloc() condition and triggers a verifier_bug(), leading to a BPF_WARN_ONCE. If it has NON_OWN_REF, it bypasses the verifier_bug() check entirely, and proceeds to allow a memory write to the untrusted pointer. Could a malicious BPF program exploit this to achieve a local denial of service via panic_on_warn or a use-after-free memory write? > if (!type_is_ptr_alloc_obj(reg->type)) { > verbose(env, "%s is neither owning or non-owning ref\n", > reg_arg_name(env, argno)); [ ... ] -- Sashiko AI review · https://sashiko.dev/#/patchset/20260726235030.1152542-1-dingning04@gmail.com?part=2 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH bpf v2 2/2] bpf: Reject untrusted pointers in refcount_acquire 2026-07-27 0:13 ` sashiko-bot @ 2026-07-27 0:40 ` Ning Ding 0 siblings, 0 replies; 7+ messages in thread From: Ning Ding @ 2026-07-27 0:40 UTC (permalink / raw) To: sashiko-reviews; +Cc: bpf This seems to be a separate issue from the refcount_acquire argument check... For a pointer without NON_OWN_REF, code inspection shows that direct access can reach verifier_bug(). If that warning is emitted, a system configured with panic_on_warn may panic. (haven't reproduced that yet) In my runtime experiment, the stale address was reused for another BPF object before physical reclamation. A read through the stale pointer returned a value belonging to the recycled object. And I did not observe a WARN, panic, physical-kfree UAF, or a successful stale write in my experiment configuration. So the current experimental evidence shows only a stale read from a recycled object, while the panic only remains possibilities in the source code, but haven't done any experiments to prove that it is feasible. Regards, Ning Ding On Sun, Jul 26, 2026 at 5:13 PM <sashiko-bot@kernel.org> wrote: > > Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: > > Pre-existing issues: > - [Critical] check_ptr_to_btf_access() incorrectly allows writes to PTR_UNTRUSTED allocated objects or triggers a verifier_bug WARN_ONCE when reading from them. > -- > > --- Patch [2]: [PATCH bpf v2 2/2] bpf: Reject untrusted pointers in refcount_acquire --- > commit 80e6c61503b2eee2d4804b0a7ec8927827ed7d92 > Author: Ning Ding <dingning04@gmail.com> > > bpf: Reject untrusted pointers in refcount_acquire > > This commit fixes an issue where a refcounted map kptr could still be passed > to bpf_refcount_acquire() after being marked PTR_UNTRUSTED due to > bpf_rcu_read_unlock(). It updates check_kfunc_args() to reject PTR_UNTRUSTED > arguments for KF_ARG_PTR_TO_REFCOUNTED_KPTR. > > Link: https://lore.kernel.org/r/20260726021304.97ED91F000E9@smtp.kernel.org > > > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c > > index 1e7343b625de5..63b1d997fe804 100644 > > --- a/kernel/bpf/verifier.c > > +++ b/kernel/bpf/verifier.c > > @@ -12414,6 +12414,11 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_ > > meta->subprogno = reg->subprogno; > > break; > > case KF_ARG_PTR_TO_REFCOUNTED_KPTR: > > + if (reg->type & PTR_UNTRUSTED) { > > + verbose(env, "%s is an untrusted refcounted kptr\n", > > + reg_arg_name(env, argno)); > > + return -EACCES; > > + } > > [Severity: Critical] > This is a pre-existing issue, but I noticed a similar problem with > PTR_UNTRUSTED handling in check_ptr_to_btf_access() for allocated objects: > > kernel/bpf/verifier.c:check_ptr_to_btf_access() { > ... > if (atype != BPF_READ && !type_is_ptr_alloc_obj(reg->type)) { > verbose(env, "only read is supported\n"); > return -EACCES; > } > > if (type_is_alloc(reg->type) && !type_is_non_owning_ref(reg->type) && > !(reg->type & MEM_RCU) && !reg_is_referenced(env, reg)) { > verifier_bug(env, "allocated object must have a referenced id"); > return -EFAULT; > } > ... > } > > Does this logic incorrectly allow writes to PTR_UNTRUSTED allocated objects > or trigger a verifier_bug WARN_ONCE when reading from them? > > If a program loads a program-allocated kptr containing an RCU-protected field > inside bpf_rcu_read_lock(), the verifier marks it MEM_ALLOC | MEM_RCU (and > NON_OWN_REF if it contains a bpf_rb_node or bpf_list_node). When the program > calls bpf_rcu_read_unlock(), it strips MEM_RCU and adds PTR_UNTRUSTED. > > If the program subsequently tries to read or write this pointer, > type_is_ptr_alloc_obj(reg->type) evaluates to true because it ignores > PTR_UNTRUSTED, bypassing the read-only check for writes. > > Then, if the pointer lacks NON_OWN_REF, it hits the type_is_alloc() condition > and triggers a verifier_bug(), leading to a BPF_WARN_ONCE. If it has > NON_OWN_REF, it bypasses the verifier_bug() check entirely, and proceeds to > allow a memory write to the untrusted pointer. > > Could a malicious BPF program exploit this to achieve a local denial of > service via panic_on_warn or a use-after-free memory write? > > > if (!type_is_ptr_alloc_obj(reg->type)) { > > verbose(env, "%s is neither owning or non-owning ref\n", > > reg_arg_name(env, argno)); > > [ ... ] > > -- > Sashiko AI review · https://sashiko.dev/#/patchset/20260726235030.1152542-1-dingning04@gmail.com?part=2 ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH bpf v2 2/2] bpf: Reject untrusted pointers in refcount_acquire 2026-07-26 23:50 ` [PATCH bpf v2 2/2] bpf: Reject untrusted pointers in refcount_acquire Ning Ding 2026-07-27 0:13 ` sashiko-bot @ 2026-07-27 4:50 ` Greg KH 1 sibling, 0 replies; 7+ messages in thread From: Greg KH @ 2026-07-27 4:50 UTC (permalink / raw) To: Ning Ding; +Cc: bpf, ast, daniel, andrii, eddyz87, memxor, martin.lau, davem On Sun, Jul 26, 2026 at 04:50:30PM -0700, Ning Ding wrote: > After bpf_rcu_read_unlock(), a refcounted map kptr is marked > PTR_UNTRUSTED because it is no longer protected by RCU. The > refcounted-kptr argument check ignores PTR_UNTRUSTED and still allows > bpf_refcount_acquire() on that pointer. > > However, if another thread removes the object and drops its last reference, the > stale address can later be reused for another refcounted object. A > CAP_BPF-only reproducer observed bpf_refcount_acquire() returning > non-NULL through such a stale pointer. > > Reject PTR_UNTRUSTED refcounted-kptr arguments and add a regression > test. > > Fixes: 7c50b1cb76ac ("bpf: Add bpf_refcount_acquire kfunc") > Reported-by: sashiko-bot@kernel.org > Link: https://lore.kernel.org/r/20260726021304.97ED91F000E9@smtp.kernel.org > Assisted-by: Codex:gpt-5 > Signed-off-by: Ning Ding <dingning04@gmail.com> > --- > kernel/bpf/verifier.c | 5 ++++ > .../bpf/progs/refcounted_kptr_fail.c | 27 +++++++++++++++++++ > 2 files changed, 32 insertions(+) > Hi, This is the friendly patch-bot of Greg Kroah-Hartman. You have sent him a patch that has triggered this response. He used to manually respond to these common problems, but in order to save his sanity (he kept writing the same thing over and over, yet to different people), I was created. Hopefully you will not take offence and will fix the problem in your patch and resubmit it so that it can be accepted into the Linux kernel tree. You are receiving this message because of the following common error(s) as indicated below: - You have marked a patch with a "Fixes:" tag for a commit that is in an older released kernel, yet you do not have a cc: stable line in the signed-off-by area at all, which means that the patch will not be applied to any older kernel releases. To properly fix this, please follow the documented rules in the Documentation/process/stable-kernel-rules.rst file for how to resolve this. If you wish to discuss this problem further, or you have questions about how to resolve this issue, please feel free to respond to this email and Greg will reply once he has dug out from the pending patches received from other developers. thanks, greg k-h's patch email bot ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-07-27 4:51 UTC | newest] Thread overview: 7+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-07-26 23:50 [PATCH bpf v2 0/2] bpf: Fix refcount_acquire handling for borrowed kptrs Ning Ding 2026-07-26 23:50 ` [PATCH bpf v2 1/2] bpf: Keep refcount_acquire nullable for borrowed RCU kptrs Ning Ding 2026-07-27 4:50 ` Greg KH 2026-07-26 23:50 ` [PATCH bpf v2 2/2] bpf: Reject untrusted pointers in refcount_acquire Ning Ding 2026-07-27 0:13 ` sashiko-bot 2026-07-27 0:40 ` Ning Ding 2026-07-27 4:50 ` Greg KH
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox