On Mon, Mar 17, 2025 at 02:38:13PM +0100, Sebastian Andrzej Siewior wrote:
Ricardo reported a KASAN discovered use after free in v6.6-stable.
The syzbot starts a BPF program via xdp_test_run_batch() which assigns ri->tgt_value via dev_hash_map_redirect() and the return code isn't XDP_REDIRECT it looks like nonsense. So the output in bpf_warn_invalid_xdp_action() appears once. Then the TUN driver runs another BPF program (on the same CPU) which returns XDP_REDIRECT without setting ri->tgt_value first. It invokes bpf_trace_printk() to print four characters and obtain the required return value. This is enough to get xdp_do_redirect() invoked which then accesses the pointer in tgt_value which might have been already deallocated.
This problem does not affect upstream because since commit 401cb7dae8130 ("net: Reference bpf_redirect_info via task_struct on PREEMPT_RT.")
the per-CPU variable is referenced via task's task_struct and exists on the stack during NAPI callback. Therefore it is cleared once before the first invocation and remains valid within the RCU section of the NAPI callback.
Instead of performing the huge backport of the commit (plus its fix ups) here is an alternative version which only resets the variable in question prior invoking the BPF program.
Acked-by: Toke Høiland-Jørgensen toke@kernel.org Reported-by: Ricardo Cañuelo Navarro rcn@igalia.com Closes: https://lore.kernel.org/all/20250226-20250204-kasan-slab-use-after-free-read... Fixes: 97f91a7cf04ff ("bpf: add bpf_redirect_map helper routine") Signed-off-by: Sebastian Andrzej Siewior bigeasy@linutronix.de
I discussed this with Toke, thread starts at https://lore.kernel.org/all/20250313183911.SPAmGLyw@linutronix.de/
The commit, which this by accident, is part of v6.11-rc1. I added the commit introducing map redirects as the origin of the problem which is v4.14-rc1. The code is a bit different there it seems to work similar.
What stable tree(s) is this for? Just 6.6.y? Why not older ones?
Greg, feel free to decide if this is worth a CVE.
That's not how CVEs are assigned :)
If you want one, please read the in-tree documentation we have for that.
thanks,
greg k-h