From 09b42f22f3d6ab25380a5b4cf9cf12eb354101ae Mon Sep 17 00:00:00 2001 From: Philip Yang Date: Wed, 20 Jul 2022 18:00:45 -0400 Subject: [PATCH] drm/amdkfd: Correct mmu_notifier_get failure handling If process has signal pending, mmu_notifier_get_locked fails and calls ops->free_notifier, kfd_process_free_notifier will schedule kfd_process_wq_release as process refcount is 1, but process structure is already freed. This use after free bug causes system crash with different backtrace. The fix is to increase process refcount and then decrease the refcount after mmu_notifier_get success. Signed-off-by: Philip Yang Reviewed-by: Felix Kuehling --- drivers/gpu/drm/amd/amdkfd/kfd_process.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index d8228afaa5f4b..be8de4ba3e6ee 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -1481,6 +1481,12 @@ static struct kfd_process *create_process(const struct task_struct *thread) (uintptr_t)process->mm); #ifdef HAVE_MMU_NOTIFIER_PUT + + /* Avoid free_notifier to start kfd_process_wq_release if + * mmu_notifier_get failed because of pending signal. + */ + kref_get(&process->ref); + /* MMU notifier registration must be the last call that can fail * because after this point we cannot unwind the process creation. * After this point, mmu_notifier_put will trigger the cleanup by @@ -1492,6 +1498,8 @@ static struct kfd_process *create_process(const struct task_struct *thread) goto err_register_notifier; } BUG_ON(mn != &process->mmu_notifier); + + kfd_unref_process(process); #else /* Must be last, have to use release destruction after this */ process->mmu_notifier.ops = &kfd_process_mmu_notifier_ops;