Thread (10 messages) 10 messages, 5 authors, 2026-01-06

Re: bpf: xdp: unhandled error in xdp_test_run_init_page() leads to crash

From: Martin KaFai Lau <martin.lau@linux.dev>
Date: 2025-12-18 18:26:34
Also in: bpf

On 12/18/25 2:43 AM, Yinhao Hu wrote:
Our fuzzer tool discovered a user-memory-access vulnerability in the BPF
subsystem. The vulnerability is triggered when building an `sk_buff`
from an XDP frame that has not been properly initialized due to an
unhandled initialization failure, causing the kernel to access an
invalid memory address.

Reported-by: Yinhao Hu <redacted>
Reported-by: Kaiyan Mei <redacted>
Reviewed-by: Dongliang Mu <dzm91@hust.edu.cn>

## Root Cause

`xdp_test_run_setup()` attempts to create a `page_pool` with the page
initialization callback `xdp_test_run_init_page()`.

During page initialization, `xdp_test_run_init_page()` calls
`xdp_update_frame_from_buff()` to initialize an `xdp_frame`. However, if
the available headroom in the associated `xdp_buff` is insufficient,
`xdp_update_frame_from_buff()` returns an error. This error is not
handled by `xdp_test_run_init_page()`, leaving the `xdp_frame`
uninitialized.

Later, `xdp_test_run_batch()` retrieves this `xdp_frame` from the
`page_pool`. Although it may attempt to partially reinitialize the frame
via `reset_ctx()`, the failure from `xdp_update_frame_from_buff()` is
still ignored.

Finally, `__xdp_build_skb_from_frame()` attempts to construct an
`sk_buff` from the uninitialized `xdp_frame`. It reads uninitialized
members (e.g., `data`, `headroom`, `frame_sz`) to compute a `hard_start`
address, which is then passed to `build_skb_around()`. The underlying
`__build_skb_around()` attempts to write to this invalid address,
resulting in a kernel crash.

## Execution Flow Visualization
Vulnerability Execution Flow
|
|--- 1. An XDP program is loaded with act XDP_PASS
|
|--- 2. `bpf(BPF_PROG_TEST_RUN, ...)` Syscall Execution
|    |
|    `-- bpf_test_run_xdp_live
|        |
|        `-- xdp_test_run_setup
|        |   |
|        |   `--> page_pool_create() with init callback
xdp_test_run_init_page()
|        |         |
|        |         `--> xdp_update_frame_from_buff() may fail, but error
is ignored, leaving xdp_frame uninitialized
|        |
|        `-- xdp_test_run_batch
|             |
|             |--> page_pool_dev_alloc_pages() returns page with
uninitialized xdp_frame
|             |
|             `--> xdp_recv_frames
|                   |
|                   |--> __xdp_build_skb_from_frame() reads
uninitialized xdpf members, computes invalid hard_start address, passes
it to build_skb_around()
|                   |
|                   `--> __build_skb_around() writes to invalid address
-> CRASH
This looks a legit issue. Toke, please help to take a look.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help