Skip to content

Commit c1da3df

Browse files
Schandna-gitinitAlexei Starovoitov
authored andcommitted
bpf: Prevent nesting overflow in bpf_try_get_buffers
bpf_try_get_buffers() returns one of multiple per-CPU buffers based on a per-CPU nesting counter. This mechanism expects that buffers are not endlessly acquired before being returned. migrate_disable() ensures that a task remains on the same CPU, but it does not prevent the task from being preempted by another task on that CPU. Without disabled preemption, a task may be preempted while holding a buffer, allowing another task to run on same CPU and acquire an additional buffer. Several such preemptions can cause the per-CPU nest counter to exceed MAX_BPRINTF_NEST_LEVEL and trigger the warning in bpf_try_get_buffers(). Adding preempt_disable()/preempt_enable() around buffer acquisition and release prevents this task preemption and preserves the intended bounded nesting behavior. Reported-by: [email protected] Closes: https://lore.kernel.org/all/[email protected]/ Fixes: 4223bf8 ("bpf: Remove preempt_disable in bpf_try_get_buffers") Suggested-by: Yonghong Song <[email protected]> Reviewed-by: Sebastian Andrzej Siewior <[email protected]> Signed-off-by: Sahil Chandna <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 93ce3be commit c1da3df

File tree

1 file changed

+3
-0
lines changed

1 file changed

+3
-0
lines changed

kernel/bpf/helpers.c

Lines changed: 3 additions & 0 deletions
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]);
@@ -789,6 +791,7 @@ void bpf_put_buffers(void)
789791
if (WARN_ON_ONCE(this_cpu_read(bpf_bprintf_nest_level) == 0))
790792
return;
791793
this_cpu_dec(bpf_bprintf_nest_level);
794+
preempt_enable();
792795
}
793796

794797
void bpf_bprintf_cleanup(struct bpf_bprintf_data *data)

0 commit comments

Comments
 (0)