| From 508518de9b4e8972b6fe8c852483cd69e3d7135b Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Mon, 8 Apr 2024 09:46:20 +0200 |
| Subject: kunit: Fix kthread reference |
| MIME-Version: 1.0 |
| Content-Type: text/plain; charset=UTF-8 |
| Content-Transfer-Encoding: 8bit |
| |
| From: Mickaël Salaün <mic@digikod.net> |
| |
| [ Upstream commit f8aa1b98ce40184521ed95ec26cc115a255183b2 ] |
| |
| There is a race condition when a kthread finishes after the deadline and |
| before the call to kthread_stop(), which may lead to use after free. |
| |
| Cc: Brendan Higgins <brendanhiggins@google.com> |
| Cc: Shuah Khan <skhan@linuxfoundation.org> |
| Reviewed-by: Kees Cook <keescook@chromium.org> |
| Fixes: adf505457032 ("kunit: fix UAF when run kfence test case test_gfpzero") |
| Reviewed-by: David Gow <davidgow@google.com> |
| Reviewed-by: Rae Moar <rmoar@google.com> |
| Signed-off-by: Mickaël Salaün <mic@digikod.net> |
| Link: https://lore.kernel.org/r/20240408074625.65017-3-mic@digikod.net |
| Signed-off-by: Shuah Khan <skhan@linuxfoundation.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| lib/kunit/try-catch.c | 9 ++++++--- |
| 1 file changed, 6 insertions(+), 3 deletions(-) |
| |
| diff --git a/lib/kunit/try-catch.c b/lib/kunit/try-catch.c |
| index f7825991d576a..d9d1df28cc52e 100644 |
| --- a/lib/kunit/try-catch.c |
| +++ b/lib/kunit/try-catch.c |
| @@ -11,6 +11,7 @@ |
| #include <linux/completion.h> |
| #include <linux/kernel.h> |
| #include <linux/kthread.h> |
| +#include <linux/sched/task.h> |
| |
| #include "try-catch-impl.h" |
| |
| @@ -65,13 +66,14 @@ void kunit_try_catch_run(struct kunit_try_catch *try_catch, void *context) |
| try_catch->context = context; |
| try_catch->try_completion = &try_completion; |
| try_catch->try_result = 0; |
| - task_struct = kthread_run(kunit_generic_run_threadfn_adapter, |
| - try_catch, |
| - "kunit_try_catch_thread"); |
| + task_struct = kthread_create(kunit_generic_run_threadfn_adapter, |
| + try_catch, "kunit_try_catch_thread"); |
| if (IS_ERR(task_struct)) { |
| try_catch->catch(try_catch->context); |
| return; |
| } |
| + get_task_struct(task_struct); |
| + wake_up_process(task_struct); |
| |
| time_remaining = wait_for_completion_timeout(&try_completion, |
| kunit_test_timeout()); |
| @@ -81,6 +83,7 @@ void kunit_try_catch_run(struct kunit_try_catch *try_catch, void *context) |
| kthread_stop(task_struct); |
| } |
| |
| + put_task_struct(task_struct); |
| exit_code = try_catch->try_result; |
| |
| if (!exit_code) |
| -- |
| 2.43.0 |
| |