All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.