summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorKP Singh <kpsingh@kernel.org>2023-06-02 02:26:12 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-06-14 11:13:01 +0200
commitc85bee3a4ae17c09aa6cdf8c7fb0f0536139daad (patch)
tree4afccd9220dd5989cfc9f24f4c9732033e3da3c5 /kernel
parent54c8aea7e888b4d75682441a53797383106ae14d (diff)
downloadlinux-stable-c85bee3a4ae17c09aa6cdf8c7fb0f0536139daad.tar.gz
linux-stable-c85bee3a4ae17c09aa6cdf8c7fb0f0536139daad.tar.bz2
linux-stable-c85bee3a4ae17c09aa6cdf8c7fb0f0536139daad.zip
bpf: Fix UAF in task local storage
[ Upstream commit b0fd1852bcc21accca6260ef245356d5c141ff66 ] 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> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/fork.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/kernel/fork.c b/kernel/fork.c
index 68eab6ce3085..1906230a000e 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -470,6 +470,7 @@ void free_task(struct task_struct *tsk)
arch_release_task_struct(tsk);
if (tsk->flags & PF_KTHREAD)
free_kthread_struct(tsk);
+ bpf_task_storage_free(tsk);
free_task_struct(tsk);
}
EXPORT_SYMBOL(free_task);
@@ -753,7 +754,6 @@ void __put_task_struct(struct task_struct *tsk)
cgroup_free(tsk);
task_numa_free(tsk, true);
security_task_free(tsk);
- bpf_task_storage_free(tsk);
exit_creds(tsk);
delayacct_tsk_free(tsk);
put_signal_struct(tsk->signal);