Skip to content

Commit 269e7e9

Browse files
Schandna-gitinitKernel Patches Daemon
authored andcommitted
bpf: use preempt_disable/enable() to protect bpf_bprintf_buffers nesting
The bpf_bprintf_prepare() and related helpers (bpf_try_get_buffers() / bpf_put_buffers()) rely on a per-CPU counter bpf_bprintf_nest_level to manage nested buffer usage. However, when invoked from different contexts (process, softirq, NMI), the nesting counter can become inconsistent if task migration occurs between CPUs during these operations. This can result in warnings such as: WARNING: CPU: 1 PID: 6145 at kernel/bpf/helpers.c:781 bpf_try_get_buffers kernel/bpf/helpers.c:781 [inline] WARNING: CPU: 1 PID: 6145 at kernel/bpf/helpers.c:781 bpf_bprintf_prepare+0x12cf/0x13a0 kernel/bpf/helpers.c:834 Having only migrate_disable is insufficient here to prevent nesting, hence add preempt_disable()/enable() around buffer acquisition and release. Reported-by: [email protected] Closes: https://syzkaller.appspot.com/bug?extid=b0cff308140f79a9c4cb Fixes: 7c33e97 ("bpf: Do not disable preemption in bpf_test_run().") Suggested-by: Yonghong Song <[email protected]> Signed-off-by: Sahil Chandna <[email protected]>
1 parent 4eb9670 commit 269e7e9

File tree

1 file changed

+6
-1
lines changed

1 file changed

+6
-1
lines changed

kernel/bpf/helpers.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -774,9 +774,11 @@ int bpf_try_get_buffers(struct bpf_bprintf_buffers **bufs)
774774
{
775775
int nest_level;
776776

777+
preempt_disable();
777778
nest_level = this_cpu_inc_return(bpf_bprintf_nest_level);
778779
if (WARN_ON_ONCE(nest_level > MAX_BPRINTF_NEST_LEVEL)) {
779780
this_cpu_dec(bpf_bprintf_nest_level);
781+
preempt_enable();
780782
return -EBUSY;
781783
}
782784
*bufs = this_cpu_ptr(&bpf_bprintf_bufs[nest_level - 1]);
@@ -786,9 +788,12 @@ int bpf_try_get_buffers(struct bpf_bprintf_buffers **bufs)
786788

787789
void bpf_put_buffers(void)
788790
{
789-
if (WARN_ON_ONCE(this_cpu_read(bpf_bprintf_nest_level) == 0))
791+
if (WARN_ON_ONCE(this_cpu_read(bpf_bprintf_nest_level) == 0)) {
792+
preempt_enable();
790793
return;
794+
}
791795
this_cpu_dec(bpf_bprintf_nest_level);
796+
preempt_enable();
792797
}
793798

794799
void bpf_bprintf_cleanup(struct bpf_bprintf_data *data)

0 commit comments

Comments
 (0)