BPF List
 help / color / mirror / Atom feed
* [PATCH bpf-next v4 0/3] bpf: Fix task work scheduling races
@ 2026-09-29  7:27 Yun Lu
  2026-09-29  7:27 ` [PATCH bpf-next v4 1/3] bpf: Fix NULL task dereference in task work cancellation Yun Lu
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Yun Lu @ 2026-09-29  7:27 UTC (permalink / raw)
  To: ast, daniel, andrii, eddyz87, memxor, martin.lau, song,
	yonghong.song, jolsa, emil, ihor.solodrai
  Cc: yatsenko, bpf

From: Yun Lu <luyun@kylinos.cn>

This series fixes two races in the bpf_task_work scheduling kfuncs and
adds a regression test for them.

Patch 1 fixes a NULL task dereference: the callback can clear ctx->task
before the scheduling irq_work handler attempts cancellation, so the
handler now captures the task pointer before publishing the callback and
relies on its existing RCU read-side section, which covers the captured
task because bpf_task_release() is put_task_struct_rcu_user().

Patch 2 stops a new round from reusing the context while the previous
scheduling irq_work is still BUSY.  Without it, a delayed handler can
consume the new round's SCHEDULING state, leaving the context stuck in a
false SCHEDULED that later routes deletion into task_work_cancel() with
a NULL task.

Patch 3 adds a 1500-round cross-CPU test racing scheduling, callback
completion and map-value deletion.

Changes since v3:

- Drop the get_task_struct()/put_task_struct() pair: capturing the
  pointer before task_work_add() is sufficient, since
  bpf_task_release() is put_task_struct_rcu_user() and the handler's
  RCU read-side section keeps the captured task alive.  Reword the
  RCU explanation.
- Split the BUSY check and the one-time irq_work initialization into
  a separate patch 2, with the full interleaving and the failure it
  prevents.
- Selftest code unchanged; commit message wording only.

v3: https://lore.kernel.org/all/20260922100042.136818-1-luyun_611@163.com/

Changes since v2:

- Kernel: drop irq_work_sync() from the callback and both
  WARN_ON_ONCE() checks, as requested in review.  Following the
  suggested direction, the scheduling handler now takes its own task
  reference around task_work_add() and the post-add cancellation; the
  temporary ctx refcount from v2 is gone as well.  The callback ends
  up unchanged from upstream.
- The BUSY check in acquire is kept: without it a handler delayed
  between task_work_add() and its state cmpxchg can flip the next
  round into a bogus SCHEDULED, which later routes map-value deletion
  into task_work_cancel() with an already-reset ctx->task.
- Selftest is unchanged apart from the rebase.

v2: https://lore.kernel.org/all/20260921101453.69273-1-luyun_611@163.com/

Changes since v1:

- Kernel: rework the fix per review feedback.  Replace the round_refs
  ownership counter and the extra irq_work objects with a completion
  edge: the callback claims RUNNING and waits for the scheduling
  irq_work via irq_work_sync(), plus one temporary reference from the
  existing ctx refcount and a BUSY check covering the add-failure
  path.  No context fields or states are added.
- Selftest: address review feedback (single packed result store,
  bounded thread-start wait, tolerate the expected deletion-race
  outcomes).

v1: https://lore.kernel.org/bpf/20260918080014.54012-1-luyun_611@163.com/

Testing:

- Built with KASAN, lockdep, PROVE_RCU, DEBUG_ATOMIC_SLEEP and
  KMEMLEAK; test_progs -t task_work and 900 stress rounds in QEMU are
  clean, no leaks reported.
- Replayed the deterministic reproducer (debug-delay only, not part of
  the series): without the fixes it panics reliably in
  task_work_cancel(); with them the callback stays non-blocking and
  the guest stays healthy.
- Directed delay tests cover both cancellation paths and both BUSY
  rejection paths.  The cross-round interleaving from patch 2's commit
  log crashes the kernel without patch 2 and survives with it.

Yun Lu (3):
  bpf: Fix NULL task dereference in task work cancellation
  bpf: Prevent task work context reuse while irq_work is busy
  selftests/bpf: Add task work scheduling race test

 kernel/bpf/helpers.c                          |  54 +++-
 .../selftests/bpf/prog_tests/test_task_work.c | 283 ++++++++++++++++++
 .../selftests/bpf/progs/task_work_race.c      | 126 ++++++++
 3 files changed, 453 insertions(+), 10 deletions(-)
 create mode 100644 tools/testing/selftests/bpf/progs/task_work_race.c


base-commit: 5dd1818b15d98d4a20806cd00b1b40320b06004f
-- 
2.43.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-09-30  8:38 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-29  7:27 [PATCH bpf-next v4 0/3] bpf: Fix task work scheduling races Yun Lu
2026-09-29  7:27 ` [PATCH bpf-next v4 1/3] bpf: Fix NULL task dereference in task work cancellation Yun Lu
2026-09-29  7:27 ` [PATCH bpf-next v4 2/3] bpf: Prevent task work context reuse while irq_work is busy Yun Lu
2026-09-29 12:02   ` Mykyta Yatsenko
2026-09-29  7:28 ` [PATCH bpf-next v4 3/3] selftests/bpf: Add task work scheduling race test Yun Lu
2026-09-29  8:12   ` bot+bpf-ci
2026-09-29 12:00     ` Mykyta Yatsenko
2026-09-30  8:37       ` luyun

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox