BPF List
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Yun Lu" <luyun_611@163.com>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH bpf-next v3 4/6] bpf: Invalidate async callbacks before detaching them
Date: Wed, 11 Nov 2026 04:22:50 +0000	[thread overview]
Message-ID: <sashiko-outbox-208275@kernel.org> (raw)
In-Reply-To: <20261111024333.228633-5-luyun_611@163.com>

Thank you for your contribution! Sashiko AI review found 1 potential
issue to consider:
- [Medium] bpf: stale async->cb pointer when losing xchg() race in
  bpf_async_cancel_and_free()
--

commit 686504449c958e635d8414edba153676c8d63adc
Author: Yun Lu <luyun@kylinos.cn>

bpf: Invalidate async callbacks before detaching them

This commit changes bpf_async_cancel_and_free() to clear cb->map with xchg()
under RCU before clearing async->cb, so that a callback object is invalidated
before it is detached from the map value slot.

> diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
> index a08b2af56ee64..716be7a852b58 100644
> --- a/kernel/bpf/helpers.c
> +++ b/kernel/bpf/helpers.c
> @@ -1747,15 +1747,18 @@ static void bpf_async_cancel_and_free(struct bpf_async_kern *async)
>  {
>  	struct bpf_async_cb *cb;
>  
> -	if (!READ_ONCE(async->cb))
> +	/* Another canceller can release the map-owned cb reference. */
> +	guard(rcu)();
> +	/* Order unlink before reading async->cb, including an empty slot. */
> +	smp_mb();
> +	/* Acquire any invalidation published before the slot was cleared. */
> +	cb = smp_load_acquire(&async->cb);
> +	/* Only the first invalidator detaches cb and drops the map's reference. */
> +	if (!cb || !xchg(&cb->map, NULL))
>  		return;
>  
> -	cb = xchg(&async->cb, NULL);
> -	if (!cb)
> -		return;
> +	WRITE_ONCE(async->cb, NULL);

[Severity: Medium]
Can a losing canceller return from bpf_async_cancel_and_free() while
async->cb is still non-NULL?

Before this patch, xchg(&async->cb, NULL) guaranteed that async->cb was
NULL whenever bpf_async_cancel_and_free() returned.  With the split between
xchg(&cb->map, NULL) and WRITE_ONCE(async->cb, NULL), a second canceller
can observe the invalidated cb and return early before the slot is cleared:

CPU0                              CPU1
array_map_update_elem()           array_map_update_elem()
  bpf_obj_cancel_fields()           copy_map_value()
    bpf_async_cancel_and_free()     bpf_obj_cancel_fields()
      cb = smp_load_acquire(...)      bpf_async_cancel_and_free()
      xchg(&cb->map, NULL)              cb = smp_load_acquire(...)
                                        !xchg(&cb->map, NULL)
                                        return;
                                  bpf_timer_init()
                                    __bpf_async_init()
                                      READ_ONCE(async->cb) != NULL
                                      return -EBUSY;  <-- spurious failure
      WRITE_ONCE(async->cb, NULL)

The same race occurs on a single CPU if an interrupt or NMI BPF program
updates the element and calls bpf_timer_init() or bpf_wq_init() while the
interrupted task is between xchg(&cb->map, NULL) and
WRITE_ONCE(async->cb, NULL), or when check_and_cancel_fields() races with
map_release_uref() before recycling a hash map element.

Having the losing canceller also clear the slot (for example via
cmpxchg(&async->cb, cb, NULL)) before returning would preserve the
guarantee that async->cb is NULL on return without overwriting a newly
published callback.

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20261111024333.228633-1-luyun_611@163.com?part=4

  reply	other threads:[~2026-11-11  4:22 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-11  2:43 [PATCH bpf-next v3 0/6] bpf: Fix async callback use-after-free on map deletion Yun Lu
2026-11-11  2:43 ` [PATCH bpf-next v3 1/6] bpf: Mark task work FREED before detaching it Yun Lu
2026-11-11  3:26   ` sashiko-bot
2026-11-11  2:43 ` [PATCH bpf-next v3 2/6] bpf: Check task work value membership before scheduling Yun Lu
2026-11-11  8:19   ` bot+bpf-ci
2026-11-11  2:43 ` [PATCH bpf-next v3 3/6] selftests/bpf: Test task work scheduling on a deleted value Yun Lu
2026-11-11  2:43 ` [PATCH bpf-next v3 4/6] bpf: Invalidate async callbacks before detaching them Yun Lu
2026-11-11  4:22   ` sashiko-bot [this message]
2026-11-11  2:43 ` [PATCH bpf-next v3 5/6] bpf: Check async callback value membership in the setter Yun Lu
2026-11-11  4:43   ` sashiko-bot
2026-11-11  2:43 ` [PATCH bpf-next v3 6/6] selftests/bpf: Test wq set_callback on a deleted value Yun Lu

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=sashiko-outbox-208275@kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=bpf@vger.kernel.org \
    --cc=luyun_611@163.com \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox