From: Igor Malovitsa <igor.malovitsa@gmail.com>
To: bpf@vger.kernel.org
Cc: ast@kernel.org, daniel@iogearbox.net, andrii@kernel.org,
martin.lau@linux.dev, eddyz87@gmail.com, song@kernel.org,
yonghong.song@linux.dev, jolsa@kernel.org, memxor@gmail.com,
linux-kernel@vger.kernel.org,
Igor Malovitsa <igor.malovitsa@gmail.com>
Subject: [PATCH bpf 1/2] bpf: Load ringbuf consumer_pos under the spinlock
Date: Fri, 16 Oct 2026 00:33:17 +0000 [thread overview]
Message-ID: <20261016003318.529860-2-igor.malovitsa@gmail.com> (raw)
In-Reply-To: <20261016003318.529860-1-igor.malovitsa@gmail.com>
__bpf_ringbuf_reserve() loads consumer_pos before taking the spinlock.
Nothing bounds how stale that value is when the lock is finally taken:
other producers may have reserved, and the consumer consumed, any
amount of data meanwhile. bpf_ringbuf_has_space() compares
new_prod_pos - cons_pos as unsigned long, so on 32-bit, once positions
wrap, a value close to 2^32 bytes stale passes the check and the new
record is written over records the consumer has not read yet.
Load consumer_pos after taking the lock. producer_pos cannot move while
the lock is held and the consumer never passes producer_pos, so the
value is less than a ring behind and the difference is exact.
This needs a reservation to stall for about 4 GiB of traffic on a
32-bit kernel; it was found with a formal model of the protocol,
and reproduced using late_initcall.
Fixes: 457f44363a88 ("bpf: Implement BPF ring buffer and verifier support for it")
Assisted-by: LLM
Signed-off-by: Igor Malovitsa <igor.malovitsa@gmail.com>
---
kernel/bpf/ringbuf.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/ringbuf.c b/kernel/bpf/ringbuf.c
index 3f1013d80544..6b86c4db5108 100644
--- a/kernel/bpf/ringbuf.c
+++ b/kernel/bpf/ringbuf.c
@@ -473,11 +473,12 @@ static void *__bpf_ringbuf_reserve(struct bpf_ringbuf *rb, u64 size)
if (len > ringbuf_total_data_sz(rb))
return NULL;
- cons_pos = smp_load_acquire(&rb->consumer_pos);
-
if (raw_res_spin_lock_irqsave(&rb->spinlock, flags))
return NULL;
+ /* Under the lock, so at most one ring behind producer_pos. */
+ cons_pos = smp_load_acquire(&rb->consumer_pos);
+
pend_pos = rb->pending_pos;
prod_pos = rb->producer_pos;
new_prod_pos = prod_pos + len;
--
2.53.0
next prev parent reply other threads:[~2026-10-16 0:34 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-16 0:33 [PATCH bpf 0/2] bpf: Fix ring buffer checks on 32-bit position wrap Igor Malovitsa
2026-10-16 0:33 ` Igor Malovitsa [this message]
2026-10-16 0:47 ` [PATCH bpf 1/2] bpf: Load ringbuf consumer_pos under the spinlock sashiko-bot
2026-10-16 0:33 ` [PATCH bpf 2/2] bpf: Fix user ringbuf empty check on 32-bit position wrap Igor Malovitsa
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=20261016003318.529860-2-igor.malovitsa@gmail.com \
--to=igor.malovitsa@gmail.com \
--cc=andrii@kernel.org \
--cc=ast@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=eddyz87@gmail.com \
--cc=jolsa@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=martin.lau@linux.dev \
--cc=memxor@gmail.com \
--cc=song@kernel.org \
--cc=yonghong.song@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.