[PATCH v1] drm/amdkfd: Fix use-after-free in the process creation error path
From: Binbin Deng
Date: Fri Oct 09 2026 - 09:27:42 EST
create_process() publishes the new process in the global hash table
before the steps that can still fail:
/* alloc_notifier needs to find the process in the hash table */
hash_add_rcu(kfd_processes_table, &process->kfd_processes,
(uintptr_t)process->mm);
If a later step fails (mmu_notifier_get() with a pending signal, or
kfd_process_alloc_id()), the error path removes and frees it:
err_register_notifier:
hash_del_rcu(&process->kfd_processes);
svm_range_list_fini(process);
...
kfree(process);
hash_del_rcu() only unlinks the node; readers that entered an SRCU
read-side critical section before the deletion can still be walking
the hash bucket and using the node. The unconditional kfree() that
follows is not covered by any SRCU grace period, so such a reader can
obtain and dereference freed memory.
The readers are the GPU interrupt and ioctl lookup helpers, which run
under srcu_read_lock(&kfd_processes_srcu) only:
kfd_lookup_process_by_pasid() iterates the whole table with
hash_for_each_rcu and dereferences p->pdds[] of every entry;
kfd_lookup_process_by_id() and kfd_lookup_process_by_mm() match and
return the process for further use.
The normal removal path (kfd_process_table_remove()) already executes
synchronize_srcu(&kfd_processes_srcu) after hash_del_rcu(); only the
error rollback path misses it. The race is reachable by an unprivileged
GPU compute user: a thread whose process creation fails (e.g. ioctl
interrupted by SIGKILL at mmu_notifier_get) while another thread is
servicing a GPU interrupt that walks the process table.
Fix this by waiting for an SRCU grace period in the error path after
unlinking the process, before the object is freed.
Fixes: 0029cab3146a ("drm/amdkfd: fix a use after free race with mmu_notifer unregister")
Signed-off-by: Binbin Deng <18983559317@xxxxxxx>
---
drivers/gpu/drm/amd/amdkfd/kfd_process.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
index 0a7c1900da95..8d0e70a256f7 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c
@@ -1747,6 +1747,7 @@ struct kfd_process *create_process(const struct task_struct *thread, bool primar
kfd_process_free_id(process);
err_register_notifier:
hash_del_rcu(&process->kfd_processes);
+ synchronize_srcu(&kfd_processes_srcu);
svm_range_list_fini(process);
err_init_svm_range_list:
kfd_process_free_outstanding_kfd_bos(process);
--
2.43.0