Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bpf: Fix UAF in task local storage

When task local storage was generalized for tracing programs, the
bpf_task_local_storage callback was moved from a BPF LSM hook
callback for security_task_free LSM hook to it's own callback. But a
failure case in bad_fork_cleanup_security was missed which, when
triggered, led to a dangling task owner pointer and a subsequent
use-after-free. Move the bpf_task_storage_free to the very end of
free_task to handle all failure cases.

This issue was noticed when a BPF LSM program was attached to the
task_alloc hook on a kernel with KASAN enabled. The program used
bpf_task_storage_get to copy the task local storage from the current
task to the new task being created.

Fixes: a10787e6d58c ("bpf: Enable task local storage for tracing programs")
Reported-by: Kuba Piecuch <jpiecuch@google.com>
Signed-off-by: KP Singh <kpsingh@kernel.org>
Acked-by: Song Liu <song@kernel.org>
Link: https://lore.kernel.org/r/20230602002612.1117381-1-kpsingh@kernel.org
Signed-off-by: Martin KaFai Lau <martin.lau@kernel.org>

authored by

KP Singh and committed by
Martin KaFai Lau
b0fd1852 b320a456

+1 -1
+1 -1
kernel/fork.c
··· 627 627 arch_release_task_struct(tsk); 628 628 if (tsk->flags & PF_KTHREAD) 629 629 free_kthread_struct(tsk); 630 + bpf_task_storage_free(tsk); 630 631 free_task_struct(tsk); 631 632 } 632 633 EXPORT_SYMBOL(free_task); ··· 980 979 cgroup_free(tsk); 981 980 task_numa_free(tsk, true); 982 981 security_task_free(tsk); 983 - bpf_task_storage_free(tsk); 984 982 exit_creds(tsk); 985 983 delayacct_tsk_free(tsk); 986 984 put_signal_struct(tsk->signal);