BPF List
 help / color / mirror / Atom feed
* [PATCH v2 bpf 0/4] bpf: Fix ring buffer position wrap handling on 32-bit
@ 2026-08-14 12:48 Israel Téllez García
  2026-08-14 12:48 ` [PATCH v2 bpf 1/4] bpf: Fix pending_pos walk on 32-bit ring position wrap Israel Téllez García
                   ` (3 more replies)
  0 siblings, 4 replies; 13+ messages in thread
From: Israel Téllez García @ 2026-08-14 12:48 UTC (permalink / raw)
  To: Andrii Nakryiko, Alexei Starovoitov, Daniel Borkmann
  Cc: Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi,
	Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa,
	Emil Tsalapatis, Bing-Jhong Billy Jheng, bpf, linux-kernel,
	Israel Téllez García

Patch 1 is v1 with the (long) cast dropped, as requested: pending_pos never
runs ahead of producer_pos, so the unsigned difference is the real distance.

While looking for other places where these positions are compared as values
rather than as distances, three more turned up; patches 2-4 fix those. All
four are the same class of bug: the positions are unsigned long, they wrap at
2^32 on 32-bit architectures, Documentation/bpf/ringbuf.rst says that wrap is
expected, and therefore every comparison between them has to be written as a
difference.

Patch 1 is the one that bites in the field: four armv7 devices stopped
delivering events after exactly 4295491360 bytes had passed through a 512 KiB
ring, and with it applied one of them has since taken 10 GiB through the same
ring with no stall.

Patches 2 and 3 are both in ringbuf_avail_data_sz(). The first replaces the
max() of two positions with a comparison of their distances to producer_pos;
the second reads producer_pos before overwrite_pos, which is the order that
__bpf_ringbuf_reserve() documents as the one the consumer must use. Patch 4 is
the userspace counterpart of patch 1, in libbpf's consumer loop.

The review also pointed at __bpf_user_ringbuf_peek(), where cons_pos and
prod_pos are u64 locals loaded from unsigned long fields, so on 32-bit they
never wrap and 'cons_pos >= prod_pos' stops working. That one is not part of
this series: it is the user-space-producer ring, where producer_pos is
untrusted input, so making it wrap-safe also means re-deriving the bounds
checks that keep the kernel safe there, which is a change of a different
nature from these four.

v1: https://lore.kernel.org/bpf/20260806130214.66028-1-i.tellez@btesa.com/

v2:
 - patch 1: drop the (long) cast (Andrii Nakryiko)
 - patches 2-4: new, the other 32-bit wrap sites found while reviewing the
   rest of the file and libbpf

Israel Téllez García (4):
  bpf: Fix pending_pos walk on 32-bit ring position wrap
  bpf: Fix available-data accounting on 32-bit wrap in overwrite mode
  bpf: Read producer_pos before overwrite_pos in ringbuf_avail_data_sz()
  libbpf: Fix ring buffer consumer loop on 32-bit position wrap

 kernel/bpf/ringbuf.c    | 12 +++++++++---
 tools/lib/bpf/ringbuf.c |  2 +-
 2 files changed, 10 insertions(+), 4 deletions(-)

-- 
2.39.5


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

end of thread, other threads:[~2026-08-14 14:10 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-14 12:48 [PATCH v2 bpf 0/4] bpf: Fix ring buffer position wrap handling on 32-bit Israel Téllez García
2026-08-14 12:48 ` [PATCH v2 bpf 1/4] bpf: Fix pending_pos walk on 32-bit ring position wrap Israel Téllez García
2026-08-14 13:05   ` sashiko-bot
2026-08-14 13:31   ` bot+bpf-ci
2026-08-14 12:48 ` [PATCH v2 bpf 2/4] bpf: Fix available-data accounting on 32-bit wrap in overwrite mode Israel Téllez García
2026-08-14 13:04   ` sashiko-bot
2026-08-14 12:48 ` [PATCH v2 bpf 3/4] bpf: Read producer_pos before overwrite_pos in ringbuf_avail_data_sz() Israel Téllez García
2026-08-14 13:01   ` sashiko-bot
2026-08-14 13:30   ` bot+bpf-ci
2026-08-14 14:09   ` Israel Téllez
2026-08-14 12:48 ` [PATCH v2 bpf 4/4] libbpf: Fix ring buffer consumer loop on 32-bit position wrap Israel Téllez García
2026-08-14 13:07   ` sashiko-bot
2026-08-14 13:31   ` bot+bpf-ci

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