linux-hardening.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/7] Handle faults in KUnit tests
@ 2024-03-19 10:48 Mickaël Salaün
  2024-03-19 10:48 ` [PATCH v3 1/7] kunit: Handle thread creation error Mickaël Salaün
                   ` (6 more replies)
  0 siblings, 7 replies; 15+ messages in thread
From: Mickaël Salaün @ 2024-03-19 10:48 UTC (permalink / raw)
  To: Brendan Higgins, David Gow, Rae Moar, Shuah Khan
  Cc: Mickaël Salaün, Alan Maguire, Borislav Petkov,
	Dave Hansen, H . Peter Anvin, Ingo Molnar, James Morris,
	Kees Cook, Luis Chamberlain, Madhavan T . Venkataraman,
	Marco Pagani, Paolo Bonzini, Sean Christopherson, Stephen Boyd,
	Thara Gopinath, Thomas Gleixner, Vitaly Kuznetsov, Wanpeng Li,
	Zahra Tarkhani, kvm, linux-hardening, linux-hyperv, linux-kernel,
	linux-security-module, linux-um, x86

Hi,

This patch series teaches KUnit to handle kthread faults as errors, and
it brings a few related fixes and improvements.

Shuah, everything should be OK now, could you please merge this series?

All these tests pass (on top of v6.8):
./tools/testing/kunit/kunit.py run --alltests
./tools/testing/kunit/kunit.py run --alltests --arch x86_64
./tools/testing/kunit/kunit.py run --alltests --arch arm64 \
  --cross_compile=aarch64-linux-gnu-

I added Reviewed-by, Tested-by and Fixes tags according to previous
review.  I improved a commit message and added a comment.

A new test case check NULL pointer dereference, which wasn't possible
before.

This is useful to test current kernel self-protection mechanisms or
future ones such as Heki: https://github.com/heki-linux

Previous version:
v2: https://lore.kernel.org/r/20240301194037.532117-1-mic@digikod.net
v1: https://lore.kernel.org/r/20240229170409.365386-1-mic@digikod.net

Regards,

Mickaël Salaün (7):
  kunit: Handle thread creation error
  kunit: Fix kthread reference
  kunit: Fix timeout message
  kunit: Handle test faults
  kunit: Fix KUNIT_SUCCESS() calls in iov_iter tests
  kunit: Print last test location on fault
  kunit: Add tests for fault

 include/kunit/test.h      | 24 ++++++++++++++++++---
 include/kunit/try-catch.h |  3 ---
 lib/kunit/kunit-test.c    | 45 ++++++++++++++++++++++++++++++++++++++-
 lib/kunit/try-catch.c     | 38 ++++++++++++++++++++++-----------
 lib/kunit_iov_iter.c      | 18 ++++++++--------
 5 files changed, 100 insertions(+), 28 deletions(-)


base-commit: e8f897f4afef0031fe618a8e94127a0934896aba
-- 
2.44.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v3 1/7] kunit: Handle thread creation error
  2024-03-19 10:48 [PATCH v3 0/7] Handle faults in KUnit tests Mickaël Salaün
@ 2024-03-19 10:48 ` Mickaël Salaün
  2024-03-19 10:48 ` [PATCH v3 2/7] kunit: Fix kthread reference Mickaël Salaün
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2024-03-19 10:48 UTC (permalink / raw)
  To: Brendan Higgins, David Gow, Rae Moar, Shuah Khan
  Cc: Mickaël Salaün, Alan Maguire, Borislav Petkov,
	Dave Hansen, H . Peter Anvin, Ingo Molnar, James Morris,
	Kees Cook, Luis Chamberlain, Madhavan T . Venkataraman,
	Marco Pagani, Paolo Bonzini, Sean Christopherson, Stephen Boyd,
	Thara Gopinath, Thomas Gleixner, Vitaly Kuznetsov, Wanpeng Li,
	Zahra Tarkhani, kvm, linux-hardening, linux-hyperv, linux-kernel,
	linux-security-module, linux-um, x86

Previously, if a thread creation failed (e.g. -ENOMEM), the function was
called (kunit_catch_run_case or kunit_catch_run_case_cleanup) without
marking the test as failed.  Instead, fill try_result with the error
code returned by kthread_run(), which will mark the test as failed and
print "internal error occurred...".

Cc: Brendan Higgins <brendanhiggins@google.com>
Cc: Shuah Khan <skhan@linuxfoundation.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: Rae Moar <rmoar@google.com>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20240319104857.70783-2-mic@digikod.net
---

Changes since v2:
* Add Rae's and David's Reviewed-by.

Changes since v1:
* Add Kees's Reviewed-by.
---
 lib/kunit/try-catch.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/kunit/try-catch.c b/lib/kunit/try-catch.c
index f7825991d576..a5cb2ef70a25 100644
--- a/lib/kunit/try-catch.c
+++ b/lib/kunit/try-catch.c
@@ -69,6 +69,7 @@ void kunit_try_catch_run(struct kunit_try_catch *try_catch, void *context)
 				  try_catch,
 				  "kunit_try_catch_thread");
 	if (IS_ERR(task_struct)) {
+		try_catch->try_result = PTR_ERR(task_struct);
 		try_catch->catch(try_catch->context);
 		return;
 	}
-- 
2.44.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 2/7] kunit: Fix kthread reference
  2024-03-19 10:48 [PATCH v3 0/7] Handle faults in KUnit tests Mickaël Salaün
  2024-03-19 10:48 ` [PATCH v3 1/7] kunit: Handle thread creation error Mickaël Salaün
@ 2024-03-19 10:48 ` Mickaël Salaün
  2024-03-19 10:48 ` [PATCH v3 3/7] kunit: Fix timeout message Mickaël Salaün
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2024-03-19 10:48 UTC (permalink / raw)
  To: Brendan Higgins, David Gow, Rae Moar, Shuah Khan
  Cc: Mickaël Salaün, Alan Maguire, Borislav Petkov,
	Dave Hansen, H . Peter Anvin, Ingo Molnar, James Morris,
	Kees Cook, Luis Chamberlain, Madhavan T . Venkataraman,
	Marco Pagani, Paolo Bonzini, Sean Christopherson, Stephen Boyd,
	Thara Gopinath, Thomas Gleixner, Vitaly Kuznetsov, Wanpeng Li,
	Zahra Tarkhani, kvm, linux-hardening, linux-hyperv, linux-kernel,
	linux-security-module, linux-um, x86

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/20240319104857.70783-3-mic@digikod.net
---

Changes since v2:
* Add Fixes tag as suggested by David.
* Add David's and Rae's Reviewed-by.

Changes since v1:
* Add Kees's Reviewed-by.
---
 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 a5cb2ef70a25..73f5007f20ea 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,14 +66,15 @@ 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->try_result = PTR_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());
@@ -82,6 +84,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.44.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 3/7] kunit: Fix timeout message
  2024-03-19 10:48 [PATCH v3 0/7] Handle faults in KUnit tests Mickaël Salaün
  2024-03-19 10:48 ` [PATCH v3 1/7] kunit: Handle thread creation error Mickaël Salaün
  2024-03-19 10:48 ` [PATCH v3 2/7] kunit: Fix kthread reference Mickaël Salaün
@ 2024-03-19 10:48 ` Mickaël Salaün
  2024-03-19 10:48 ` [PATCH v3 4/7] kunit: Handle test faults Mickaël Salaün
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2024-03-19 10:48 UTC (permalink / raw)
  To: Brendan Higgins, David Gow, Rae Moar, Shuah Khan
  Cc: Mickaël Salaün, Alan Maguire, Borislav Petkov,
	Dave Hansen, H . Peter Anvin, Ingo Molnar, James Morris,
	Kees Cook, Luis Chamberlain, Madhavan T . Venkataraman,
	Marco Pagani, Paolo Bonzini, Sean Christopherson, Stephen Boyd,
	Thara Gopinath, Thomas Gleixner, Vitaly Kuznetsov, Wanpeng Li,
	Zahra Tarkhani, kvm, linux-hardening, linux-hyperv, linux-kernel,
	linux-security-module, linux-um, x86

The exit code is always checked, so let's properly handle the -ETIMEDOUT
error code.

Cc: Brendan Higgins <brendanhiggins@google.com>
Cc: Shuah Khan <skhan@linuxfoundation.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
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/20240319104857.70783-4-mic@digikod.net
---

Changes since v2:
* Add Rae's and David's Reviewed-by.

Changes since v1:
* Add Kees's Reviewed-by.
---
 lib/kunit/try-catch.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/lib/kunit/try-catch.c b/lib/kunit/try-catch.c
index 73f5007f20ea..cab8b24b5d5a 100644
--- a/lib/kunit/try-catch.c
+++ b/lib/kunit/try-catch.c
@@ -79,7 +79,6 @@ void kunit_try_catch_run(struct kunit_try_catch *try_catch, void *context)
 	time_remaining = wait_for_completion_timeout(&try_completion,
 						     kunit_test_timeout());
 	if (time_remaining == 0) {
-		kunit_err(test, "try timed out\n");
 		try_catch->try_result = -ETIMEDOUT;
 		kthread_stop(task_struct);
 	}
@@ -94,6 +93,8 @@ void kunit_try_catch_run(struct kunit_try_catch *try_catch, void *context)
 		try_catch->try_result = 0;
 	else if (exit_code == -EINTR)
 		kunit_err(test, "wake_up_process() was never called\n");
+	else if (exit_code == -ETIMEDOUT)
+		kunit_err(test, "try timed out\n");
 	else if (exit_code)
 		kunit_err(test, "Unknown error: %d\n", exit_code);
 
-- 
2.44.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 4/7] kunit: Handle test faults
  2024-03-19 10:48 [PATCH v3 0/7] Handle faults in KUnit tests Mickaël Salaün
                   ` (2 preceding siblings ...)
  2024-03-19 10:48 ` [PATCH v3 3/7] kunit: Fix timeout message Mickaël Salaün
@ 2024-03-19 10:48 ` Mickaël Salaün
  2024-03-23  7:37   ` David Gow
  2024-03-19 10:48 ` [PATCH v3 5/7] kunit: Fix KUNIT_SUCCESS() calls in iov_iter tests Mickaël Salaün
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 15+ messages in thread
From: Mickaël Salaün @ 2024-03-19 10:48 UTC (permalink / raw)
  To: Brendan Higgins, David Gow, Rae Moar, Shuah Khan
  Cc: Mickaël Salaün, Alan Maguire, Borislav Petkov,
	Dave Hansen, H . Peter Anvin, Ingo Molnar, James Morris,
	Kees Cook, Luis Chamberlain, Madhavan T . Venkataraman,
	Marco Pagani, Paolo Bonzini, Sean Christopherson, Stephen Boyd,
	Thara Gopinath, Thomas Gleixner, Vitaly Kuznetsov, Wanpeng Li,
	Zahra Tarkhani, kvm, linux-hardening, linux-hyperv, linux-kernel,
	linux-security-module, linux-um, x86

Previously, when a kernel test thread crashed (e.g. NULL pointer
dereference, general protection fault), the KUnit test hanged for 30
seconds and exited with a timeout error.

Fix this issue by waiting on task_struct->vfork_done instead of the
custom kunit_try_catch.try_completion, and track the execution state by
initially setting try_result with -EINTR and only setting it to 0 if
the test passed.

Fix kunit_generic_run_threadfn_adapter() signature by returning 0
instead of calling kthread_complete_and_exit().  Because thread's exit
code is never checked, always set it to 0 to make it clear.

Fix the -EINTR error message, which couldn't be reached until now.

This is tested with a following patch.

Cc: Brendan Higgins <brendanhiggins@google.com>
Cc: Shuah Khan <skhan@linuxfoundation.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: David Gow <davidgow@google.com>
Tested-by: Rae Moar <rmoar@google.com>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20240319104857.70783-5-mic@digikod.net
---

Changes since v2:
* s/-EFAULT/-EINTR/ in commit message as spotted by Rae.
* Add a comment explaining vfork_done as suggested by David.
* Add David's Reviewed-by.
* Add Rae's Tested-by.

Changes since v1:
* Add Kees's Reviewed-by.
---
 include/kunit/try-catch.h |  3 ---
 lib/kunit/try-catch.c     | 19 ++++++++++++-------
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/include/kunit/try-catch.h b/include/kunit/try-catch.h
index c507dd43119d..7c966a1adbd3 100644
--- a/include/kunit/try-catch.h
+++ b/include/kunit/try-catch.h
@@ -14,13 +14,11 @@
 
 typedef void (*kunit_try_catch_func_t)(void *);
 
-struct completion;
 struct kunit;
 
 /**
  * struct kunit_try_catch - provides a generic way to run code which might fail.
  * @test: The test case that is currently being executed.
- * @try_completion: Completion that the control thread waits on while test runs.
  * @try_result: Contains any errno obtained while running test case.
  * @try: The function, the test case, to attempt to run.
  * @catch: The function called if @try bails out.
@@ -46,7 +44,6 @@ struct kunit;
 struct kunit_try_catch {
 	/* private: internal use only. */
 	struct kunit *test;
-	struct completion *try_completion;
 	int try_result;
 	kunit_try_catch_func_t try;
 	kunit_try_catch_func_t catch;
diff --git a/lib/kunit/try-catch.c b/lib/kunit/try-catch.c
index cab8b24b5d5a..7a3910dd78a6 100644
--- a/lib/kunit/try-catch.c
+++ b/lib/kunit/try-catch.c
@@ -18,7 +18,7 @@
 void __noreturn kunit_try_catch_throw(struct kunit_try_catch *try_catch)
 {
 	try_catch->try_result = -EFAULT;
-	kthread_complete_and_exit(try_catch->try_completion, -EFAULT);
+	kthread_exit(0);
 }
 EXPORT_SYMBOL_GPL(kunit_try_catch_throw);
 
@@ -26,9 +26,12 @@ static int kunit_generic_run_threadfn_adapter(void *data)
 {
 	struct kunit_try_catch *try_catch = data;
 
+	try_catch->try_result = -EINTR;
 	try_catch->try(try_catch->context);
+	if (try_catch->try_result == -EINTR)
+		try_catch->try_result = 0;
 
-	kthread_complete_and_exit(try_catch->try_completion, 0);
+	return 0;
 }
 
 static unsigned long kunit_test_timeout(void)
@@ -58,13 +61,11 @@ static unsigned long kunit_test_timeout(void)
 
 void kunit_try_catch_run(struct kunit_try_catch *try_catch, void *context)
 {
-	DECLARE_COMPLETION_ONSTACK(try_completion);
 	struct kunit *test = try_catch->test;
 	struct task_struct *task_struct;
 	int exit_code, time_remaining;
 
 	try_catch->context = context;
-	try_catch->try_completion = &try_completion;
 	try_catch->try_result = 0;
 	task_struct = kthread_create(kunit_generic_run_threadfn_adapter,
 				     try_catch, "kunit_try_catch_thread");
@@ -75,8 +76,12 @@ void kunit_try_catch_run(struct kunit_try_catch *try_catch, void *context)
 	}
 	get_task_struct(task_struct);
 	wake_up_process(task_struct);
-
-	time_remaining = wait_for_completion_timeout(&try_completion,
+	/*
+	 * As for a vfork(2), task_struct->vfork_done (pointing to the
+	 * underlying kthread->exited) can be used to wait for the end of a
+	 * kernel thread.
+	 */
+	time_remaining = wait_for_completion_timeout(task_struct->vfork_done,
 						     kunit_test_timeout());
 	if (time_remaining == 0) {
 		try_catch->try_result = -ETIMEDOUT;
@@ -92,7 +97,7 @@ void kunit_try_catch_run(struct kunit_try_catch *try_catch, void *context)
 	if (exit_code == -EFAULT)
 		try_catch->try_result = 0;
 	else if (exit_code == -EINTR)
-		kunit_err(test, "wake_up_process() was never called\n");
+		kunit_err(test, "try faulted\n");
 	else if (exit_code == -ETIMEDOUT)
 		kunit_err(test, "try timed out\n");
 	else if (exit_code)
-- 
2.44.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 5/7] kunit: Fix KUNIT_SUCCESS() calls in iov_iter tests
  2024-03-19 10:48 [PATCH v3 0/7] Handle faults in KUnit tests Mickaël Salaün
                   ` (3 preceding siblings ...)
  2024-03-19 10:48 ` [PATCH v3 4/7] kunit: Handle test faults Mickaël Salaün
@ 2024-03-19 10:48 ` Mickaël Salaün
  2024-03-19 10:48 ` [PATCH v3 6/7] kunit: Print last test location on fault Mickaël Salaün
  2024-03-19 10:48 ` [PATCH v3 7/7] kunit: Add tests for fault Mickaël Salaün
  6 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2024-03-19 10:48 UTC (permalink / raw)
  To: Brendan Higgins, David Gow, Rae Moar, Shuah Khan
  Cc: Mickaël Salaün, Alan Maguire, Borislav Petkov,
	Dave Hansen, H . Peter Anvin, Ingo Molnar, James Morris,
	Kees Cook, Luis Chamberlain, Madhavan T . Venkataraman,
	Marco Pagani, Paolo Bonzini, Sean Christopherson, Stephen Boyd,
	Thara Gopinath, Thomas Gleixner, Vitaly Kuznetsov, Wanpeng Li,
	Zahra Tarkhani, kvm, linux-hardening, linux-hyperv, linux-kernel,
	linux-security-module, linux-um, x86

Fix KUNIT_SUCCESS() calls to pass a test argument.

This is a no-op for now because this macro does nothing, but it will be
required for the next commit.

Cc: Brendan Higgins <brendanhiggins@google.com>
Cc: Rae Moar <rmoar@google.com>
Cc: Shuah Khan <skhan@linuxfoundation.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20240319104857.70783-6-mic@digikod.net
---

Changes since v2:
* Add David's Reviewed-by.

Changes since v1:
* Add Kees's Reviewed-by.
---
 lib/kunit_iov_iter.c | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/lib/kunit_iov_iter.c b/lib/kunit_iov_iter.c
index 859b67c4d697..27e0c8ee71d8 100644
--- a/lib/kunit_iov_iter.c
+++ b/lib/kunit_iov_iter.c
@@ -139,7 +139,7 @@ static void __init iov_kunit_copy_to_kvec(struct kunit *test)
 			return;
 	}
 
-	KUNIT_SUCCEED();
+	KUNIT_SUCCEED(test);
 }
 
 /*
@@ -194,7 +194,7 @@ static void __init iov_kunit_copy_from_kvec(struct kunit *test)
 			return;
 	}
 
-	KUNIT_SUCCEED();
+	KUNIT_SUCCEED(test);
 }
 
 struct bvec_test_range {
@@ -302,7 +302,7 @@ static void __init iov_kunit_copy_to_bvec(struct kunit *test)
 			return;
 	}
 
-	KUNIT_SUCCEED();
+	KUNIT_SUCCEED(test);
 }
 
 /*
@@ -359,7 +359,7 @@ static void __init iov_kunit_copy_from_bvec(struct kunit *test)
 			return;
 	}
 
-	KUNIT_SUCCEED();
+	KUNIT_SUCCEED(test);
 }
 
 static void iov_kunit_destroy_xarray(void *data)
@@ -453,7 +453,7 @@ static void __init iov_kunit_copy_to_xarray(struct kunit *test)
 			return;
 	}
 
-	KUNIT_SUCCEED();
+	KUNIT_SUCCEED(test);
 }
 
 /*
@@ -516,7 +516,7 @@ static void __init iov_kunit_copy_from_xarray(struct kunit *test)
 			return;
 	}
 
-	KUNIT_SUCCEED();
+	KUNIT_SUCCEED(test);
 }
 
 /*
@@ -596,7 +596,7 @@ static void __init iov_kunit_extract_pages_kvec(struct kunit *test)
 stop:
 	KUNIT_EXPECT_EQ(test, size, 0);
 	KUNIT_EXPECT_EQ(test, iter.count, 0);
-	KUNIT_SUCCEED();
+	KUNIT_SUCCEED(test);
 }
 
 /*
@@ -674,7 +674,7 @@ static void __init iov_kunit_extract_pages_bvec(struct kunit *test)
 stop:
 	KUNIT_EXPECT_EQ(test, size, 0);
 	KUNIT_EXPECT_EQ(test, iter.count, 0);
-	KUNIT_SUCCEED();
+	KUNIT_SUCCEED(test);
 }
 
 /*
@@ -753,7 +753,7 @@ static void __init iov_kunit_extract_pages_xarray(struct kunit *test)
 	}
 
 stop:
-	KUNIT_SUCCEED();
+	KUNIT_SUCCEED(test);
 }
 
 static struct kunit_case __refdata iov_kunit_cases[] = {
-- 
2.44.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 6/7] kunit: Print last test location on fault
  2024-03-19 10:48 [PATCH v3 0/7] Handle faults in KUnit tests Mickaël Salaün
                   ` (4 preceding siblings ...)
  2024-03-19 10:48 ` [PATCH v3 5/7] kunit: Fix KUNIT_SUCCESS() calls in iov_iter tests Mickaël Salaün
@ 2024-03-19 10:48 ` Mickaël Salaün
  2024-03-19 10:48 ` [PATCH v3 7/7] kunit: Add tests for fault Mickaël Salaün
  6 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2024-03-19 10:48 UTC (permalink / raw)
  To: Brendan Higgins, David Gow, Rae Moar, Shuah Khan
  Cc: Mickaël Salaün, Alan Maguire, Borislav Petkov,
	Dave Hansen, H . Peter Anvin, Ingo Molnar, James Morris,
	Kees Cook, Luis Chamberlain, Madhavan T . Venkataraman,
	Marco Pagani, Paolo Bonzini, Sean Christopherson, Stephen Boyd,
	Thara Gopinath, Thomas Gleixner, Vitaly Kuznetsov, Wanpeng Li,
	Zahra Tarkhani, kvm, linux-hardening, linux-hyperv, linux-kernel,
	linux-security-module, linux-um, x86

This helps identify the location of test faults with opportunistic calls
to _KUNIT_SAVE_LOC().  This can be useful while writing tests or
debugging them.  It is possible to call KUNIT_SUCCESS() to explicit save
last location.

Cc: Brendan Higgins <brendanhiggins@google.com>
Cc: David Gow <davidgow@google.com>
Cc: Rae Moar <rmoar@google.com>
Cc: Shuah Khan <skhan@linuxfoundation.org>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20240319104857.70783-7-mic@digikod.net
---

Changes since v2:
* Extend the commit message according to discussion with David.

Changes since v1:
* Add Kees's Reviewed-by.
---
 include/kunit/test.h  | 24 +++++++++++++++++++++---
 lib/kunit/try-catch.c | 10 +++++++---
 2 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/include/kunit/test.h b/include/kunit/test.h
index fcb4a4940ace..f3aa66eb0087 100644
--- a/include/kunit/test.h
+++ b/include/kunit/test.h
@@ -301,6 +301,8 @@ struct kunit {
 	struct list_head resources; /* Protected by lock. */
 
 	char status_comment[KUNIT_STATUS_COMMENT_SIZE];
+	/* Saves the last seen test. Useful to help with faults. */
+	struct kunit_loc last_seen;
 };
 
 static inline void kunit_set_failure(struct kunit *test)
@@ -567,6 +569,15 @@ void __printf(2, 3) kunit_log_append(struct string_stream *log, const char *fmt,
 #define kunit_err(test, fmt, ...) \
 	kunit_printk(KERN_ERR, test, fmt, ##__VA_ARGS__)
 
+/*
+ * Must be called at the beginning of each KUNIT_*_ASSERTION().
+ * Cf. KUNIT_CURRENT_LOC.
+ */
+#define _KUNIT_SAVE_LOC(test) do {					       \
+	WRITE_ONCE(test->last_seen.file, __FILE__);			       \
+	WRITE_ONCE(test->last_seen.line, __LINE__);			       \
+} while (0)
+
 /**
  * KUNIT_SUCCEED() - A no-op expectation. Only exists for code clarity.
  * @test: The test context object.
@@ -575,7 +586,7 @@ void __printf(2, 3) kunit_log_append(struct string_stream *log, const char *fmt,
  * words, it does nothing and only exists for code clarity. See
  * KUNIT_EXPECT_TRUE() for more information.
  */
-#define KUNIT_SUCCEED(test) do {} while (0)
+#define KUNIT_SUCCEED(test) _KUNIT_SAVE_LOC(test)
 
 void __noreturn __kunit_abort(struct kunit *test);
 
@@ -601,14 +612,16 @@ void __kunit_do_failed_assertion(struct kunit *test,
 } while (0)
 
 
-#define KUNIT_FAIL_ASSERTION(test, assert_type, fmt, ...)		       \
+#define KUNIT_FAIL_ASSERTION(test, assert_type, fmt, ...) do {		       \
+	_KUNIT_SAVE_LOC(test);						       \
 	_KUNIT_FAILED(test,						       \
 		      assert_type,					       \
 		      kunit_fail_assert,				       \
 		      kunit_fail_assert_format,				       \
 		      {},						       \
 		      fmt,						       \
-		      ##__VA_ARGS__)
+		      ##__VA_ARGS__);					       \
+} while (0)
 
 /**
  * KUNIT_FAIL() - Always causes a test to fail when evaluated.
@@ -637,6 +650,7 @@ void __kunit_do_failed_assertion(struct kunit *test,
 			      fmt,					       \
 			      ...)					       \
 do {									       \
+	_KUNIT_SAVE_LOC(test);						       \
 	if (likely(!!(condition_) == !!expected_true_))			       \
 		break;							       \
 									       \
@@ -698,6 +712,7 @@ do {									       \
 		.right_text = #right,					       \
 	};								       \
 									       \
+	_KUNIT_SAVE_LOC(test);						       \
 	if (likely(__left op __right))					       \
 		break;							       \
 									       \
@@ -758,6 +773,7 @@ do {									       \
 		.right_text = #right,					       \
 	};								       \
 									       \
+	_KUNIT_SAVE_LOC(test);						       \
 	if (likely((__left) && (__right) && (strcmp(__left, __right) op 0)))   \
 		break;							       \
 									       \
@@ -791,6 +807,7 @@ do {									       \
 		.right_text = #right,					       \
 	};								       \
 									       \
+	_KUNIT_SAVE_LOC(test);						       \
 	if (likely(__left && __right))					       \
 		if (likely(memcmp(__left, __right, __size) op 0))	       \
 			break;						       \
@@ -815,6 +832,7 @@ do {									       \
 do {									       \
 	const typeof(ptr) __ptr = (ptr);				       \
 									       \
+	_KUNIT_SAVE_LOC(test);						       \
 	if (!IS_ERR_OR_NULL(__ptr))					       \
 		break;							       \
 									       \
diff --git a/lib/kunit/try-catch.c b/lib/kunit/try-catch.c
index 7a3910dd78a6..d36e78095fdc 100644
--- a/lib/kunit/try-catch.c
+++ b/lib/kunit/try-catch.c
@@ -96,9 +96,13 @@ void kunit_try_catch_run(struct kunit_try_catch *try_catch, void *context)
 
 	if (exit_code == -EFAULT)
 		try_catch->try_result = 0;
-	else if (exit_code == -EINTR)
-		kunit_err(test, "try faulted\n");
-	else if (exit_code == -ETIMEDOUT)
+	else if (exit_code == -EINTR) {
+		if (test->last_seen.file)
+			kunit_err(test, "try faulted after %s:%d\n",
+				  test->last_seen.file, test->last_seen.line);
+		else
+			kunit_err(test, "try faulted before the first test\n");
+	} else if (exit_code == -ETIMEDOUT)
 		kunit_err(test, "try timed out\n");
 	else if (exit_code)
 		kunit_err(test, "Unknown error: %d\n", exit_code);
-- 
2.44.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH v3 7/7] kunit: Add tests for fault
  2024-03-19 10:48 [PATCH v3 0/7] Handle faults in KUnit tests Mickaël Salaün
                   ` (5 preceding siblings ...)
  2024-03-19 10:48 ` [PATCH v3 6/7] kunit: Print last test location on fault Mickaël Salaün
@ 2024-03-19 10:48 ` Mickaël Salaün
  2024-04-19 22:33   ` Guenter Roeck
  6 siblings, 1 reply; 15+ messages in thread
From: Mickaël Salaün @ 2024-03-19 10:48 UTC (permalink / raw)
  To: Brendan Higgins, David Gow, Rae Moar, Shuah Khan
  Cc: Mickaël Salaün, Alan Maguire, Borislav Petkov,
	Dave Hansen, H . Peter Anvin, Ingo Molnar, James Morris,
	Kees Cook, Luis Chamberlain, Madhavan T . Venkataraman,
	Marco Pagani, Paolo Bonzini, Sean Christopherson, Stephen Boyd,
	Thara Gopinath, Thomas Gleixner, Vitaly Kuznetsov, Wanpeng Li,
	Zahra Tarkhani, kvm, linux-hardening, linux-hyperv, linux-kernel,
	linux-security-module, linux-um, x86

Add a test case to check NULL pointer dereference and make sure it would
result as a failed test.

The full kunit_fault test suite is marked as skipped when run on UML
because it would result to a kernel panic.

Tested with:
./tools/testing/kunit/kunit.py run --arch x86_64 kunit_fault
./tools/testing/kunit/kunit.py run --arch arm64 \
  --cross_compile=aarch64-linux-gnu- kunit_fault

Cc: Brendan Higgins <brendanhiggins@google.com>
Cc: Rae Moar <rmoar@google.com>
Cc: Shuah Khan <skhan@linuxfoundation.org>
Reviewed-by: David Gow <davidgow@google.com>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20240319104857.70783-8-mic@digikod.net
---

Changes since v2:
* Add David's Reviewed-by.

Changes since v1:
* Remove the rodata and const test cases for now.
* Replace CONFIG_X86 check with !CONFIG_UML, and remove the "_x86"
  references.
---
 lib/kunit/kunit-test.c | 45 +++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 44 insertions(+), 1 deletion(-)

diff --git a/lib/kunit/kunit-test.c b/lib/kunit/kunit-test.c
index f7980ef236a3..0fdca5fffaec 100644
--- a/lib/kunit/kunit-test.c
+++ b/lib/kunit/kunit-test.c
@@ -109,6 +109,48 @@ static struct kunit_suite kunit_try_catch_test_suite = {
 	.test_cases = kunit_try_catch_test_cases,
 };
 
+#ifndef CONFIG_UML
+
+static void kunit_test_null_dereference(void *data)
+{
+	struct kunit *test = data;
+	int *null = NULL;
+
+	*null = 0;
+
+	KUNIT_FAIL(test, "This line should never be reached\n");
+}
+
+static void kunit_test_fault_null_dereference(struct kunit *test)
+{
+	struct kunit_try_catch_test_context *ctx = test->priv;
+	struct kunit_try_catch *try_catch = ctx->try_catch;
+
+	kunit_try_catch_init(try_catch,
+			     test,
+			     kunit_test_null_dereference,
+			     kunit_test_catch);
+	kunit_try_catch_run(try_catch, test);
+
+	KUNIT_EXPECT_EQ(test, try_catch->try_result, -EINTR);
+	KUNIT_EXPECT_TRUE(test, ctx->function_called);
+}
+
+#endif /* !CONFIG_UML */
+
+static struct kunit_case kunit_fault_test_cases[] = {
+#ifndef CONFIG_UML
+	KUNIT_CASE(kunit_test_fault_null_dereference),
+#endif /* !CONFIG_UML */
+	{}
+};
+
+static struct kunit_suite kunit_fault_test_suite = {
+	.name = "kunit_fault",
+	.init = kunit_try_catch_test_init,
+	.test_cases = kunit_fault_test_cases,
+};
+
 /*
  * Context for testing test managed resources
  * is_resource_initialized is used to test arbitrary resources
@@ -826,6 +868,7 @@ static struct kunit_suite kunit_current_test_suite = {
 
 kunit_test_suites(&kunit_try_catch_test_suite, &kunit_resource_test_suite,
 		  &kunit_log_test_suite, &kunit_status_test_suite,
-		  &kunit_current_test_suite, &kunit_device_test_suite);
+		  &kunit_current_test_suite, &kunit_device_test_suite,
+		  &kunit_fault_test_suite);
 
 MODULE_LICENSE("GPL v2");
-- 
2.44.0


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 4/7] kunit: Handle test faults
  2024-03-19 10:48 ` [PATCH v3 4/7] kunit: Handle test faults Mickaël Salaün
@ 2024-03-23  7:37   ` David Gow
  2024-03-26  9:02     ` Mickaël Salaün
  0 siblings, 1 reply; 15+ messages in thread
From: David Gow @ 2024-03-23  7:37 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: Brendan Higgins, Rae Moar, Shuah Khan, Alan Maguire,
	Borislav Petkov, Dave Hansen, H . Peter Anvin, Ingo Molnar,
	James Morris, Kees Cook, Luis Chamberlain,
	Madhavan T . Venkataraman, Marco Pagani, Paolo Bonzini,
	Sean Christopherson, Stephen Boyd, Thara Gopinath,
	Thomas Gleixner, Vitaly Kuznetsov, Wanpeng Li, Zahra Tarkhani,
	kvm, linux-hardening, linux-hyperv, linux-kernel,
	linux-security-module, linux-um, x86

[-- Attachment #1: Type: text/plain, Size: 5881 bytes --]

On Tue, 19 Mar 2024 at 18:49, Mickaël Salaün <mic@digikod.net> wrote:
>
> Previously, when a kernel test thread crashed (e.g. NULL pointer
> dereference, general protection fault), the KUnit test hanged for 30
> seconds and exited with a timeout error.
>
> Fix this issue by waiting on task_struct->vfork_done instead of the
> custom kunit_try_catch.try_completion, and track the execution state by
> initially setting try_result with -EINTR and only setting it to 0 if
> the test passed.
>
> Fix kunit_generic_run_threadfn_adapter() signature by returning 0
> instead of calling kthread_complete_and_exit().  Because thread's exit
> code is never checked, always set it to 0 to make it clear.
>
> Fix the -EINTR error message, which couldn't be reached until now.
>
> This is tested with a following patch.
>
> Cc: Brendan Higgins <brendanhiggins@google.com>
> Cc: Shuah Khan <skhan@linuxfoundation.org>
> Reviewed-by: Kees Cook <keescook@chromium.org>
> Reviewed-by: David Gow <davidgow@google.com>
> Tested-by: Rae Moar <rmoar@google.com>
> Signed-off-by: Mickaël Salaün <mic@digikod.net>
> Link: https://lore.kernel.org/r/20240319104857.70783-5-mic@digikod.net
> ---
>
> Changes since v2:
> * s/-EFAULT/-EINTR/ in commit message as spotted by Rae.
> * Add a comment explaining vfork_done as suggested by David.
> * Add David's Reviewed-by.
> * Add Rae's Tested-by.
>
> Changes since v1:
> * Add Kees's Reviewed-by.
> ---
>  include/kunit/try-catch.h |  3 ---
>  lib/kunit/try-catch.c     | 19 ++++++++++++-------
>  2 files changed, 12 insertions(+), 10 deletions(-)
>
> diff --git a/include/kunit/try-catch.h b/include/kunit/try-catch.h
> index c507dd43119d..7c966a1adbd3 100644
> --- a/include/kunit/try-catch.h
> +++ b/include/kunit/try-catch.h
> @@ -14,13 +14,11 @@
>
>  typedef void (*kunit_try_catch_func_t)(void *);
>
> -struct completion;
>  struct kunit;
>
>  /**
>   * struct kunit_try_catch - provides a generic way to run code which might fail.
>   * @test: The test case that is currently being executed.
> - * @try_completion: Completion that the control thread waits on while test runs.
>   * @try_result: Contains any errno obtained while running test case.
>   * @try: The function, the test case, to attempt to run.
>   * @catch: The function called if @try bails out.
> @@ -46,7 +44,6 @@ struct kunit;
>  struct kunit_try_catch {
>         /* private: internal use only. */
>         struct kunit *test;
> -       struct completion *try_completion;
>         int try_result;
>         kunit_try_catch_func_t try;
>         kunit_try_catch_func_t catch;
> diff --git a/lib/kunit/try-catch.c b/lib/kunit/try-catch.c
> index cab8b24b5d5a..7a3910dd78a6 100644
> --- a/lib/kunit/try-catch.c
> +++ b/lib/kunit/try-catch.c
> @@ -18,7 +18,7 @@
>  void __noreturn kunit_try_catch_throw(struct kunit_try_catch *try_catch)
>  {
>         try_catch->try_result = -EFAULT;
> -       kthread_complete_and_exit(try_catch->try_completion, -EFAULT);
> +       kthread_exit(0);

It turns out kthread_exit() is not exported, so this doesn't work if
KUnit is built as a module.

I think the options we have are:
- Add EXPORT_SYMBOL(kthread_exit).
- Keep using out own completion, and kthread_complete_and_exit()
- try_get_module() before spawning the thread, and use
module_put_and_kthread_exit().

I think all of these would be okay, but I could've missed something.

-- David

>  }
>  EXPORT_SYMBOL_GPL(kunit_try_catch_throw);
>
> @@ -26,9 +26,12 @@ static int kunit_generic_run_threadfn_adapter(void *data)
>  {
>         struct kunit_try_catch *try_catch = data;
>
> +       try_catch->try_result = -EINTR;
>         try_catch->try(try_catch->context);
> +       if (try_catch->try_result == -EINTR)
> +               try_catch->try_result = 0;
>
> -       kthread_complete_and_exit(try_catch->try_completion, 0);
> +       return 0;
>  }
>
>  static unsigned long kunit_test_timeout(void)
> @@ -58,13 +61,11 @@ static unsigned long kunit_test_timeout(void)
>
>  void kunit_try_catch_run(struct kunit_try_catch *try_catch, void *context)
>  {
> -       DECLARE_COMPLETION_ONSTACK(try_completion);
>         struct kunit *test = try_catch->test;
>         struct task_struct *task_struct;
>         int exit_code, time_remaining;
>
>         try_catch->context = context;
> -       try_catch->try_completion = &try_completion;
>         try_catch->try_result = 0;
>         task_struct = kthread_create(kunit_generic_run_threadfn_adapter,
>                                      try_catch, "kunit_try_catch_thread");
> @@ -75,8 +76,12 @@ void kunit_try_catch_run(struct kunit_try_catch *try_catch, void *context)
>         }
>         get_task_struct(task_struct);
>         wake_up_process(task_struct);
> -
> -       time_remaining = wait_for_completion_timeout(&try_completion,
> +       /*
> +        * As for a vfork(2), task_struct->vfork_done (pointing to the
> +        * underlying kthread->exited) can be used to wait for the end of a
> +        * kernel thread.
> +        */
> +       time_remaining = wait_for_completion_timeout(task_struct->vfork_done,
>                                                      kunit_test_timeout());
>         if (time_remaining == 0) {
>                 try_catch->try_result = -ETIMEDOUT;
> @@ -92,7 +97,7 @@ void kunit_try_catch_run(struct kunit_try_catch *try_catch, void *context)
>         if (exit_code == -EFAULT)
>                 try_catch->try_result = 0;
>         else if (exit_code == -EINTR)
> -               kunit_err(test, "wake_up_process() was never called\n");
> +               kunit_err(test, "try faulted\n");
>         else if (exit_code == -ETIMEDOUT)
>                 kunit_err(test, "try timed out\n");
>         else if (exit_code)
> --
> 2.44.0
>

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4014 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 4/7] kunit: Handle test faults
  2024-03-23  7:37   ` David Gow
@ 2024-03-26  9:02     ` Mickaël Salaün
  0 siblings, 0 replies; 15+ messages in thread
From: Mickaël Salaün @ 2024-03-26  9:02 UTC (permalink / raw)
  To: David Gow
  Cc: Brendan Higgins, Rae Moar, Shuah Khan, Alan Maguire,
	Borislav Petkov, Dave Hansen, H . Peter Anvin, Ingo Molnar,
	James Morris, Kees Cook, Luis Chamberlain,
	Madhavan T . Venkataraman, Marco Pagani, Paolo Bonzini,
	Sean Christopherson, Stephen Boyd, Thara Gopinath,
	Thomas Gleixner, Vitaly Kuznetsov, Wanpeng Li, Zahra Tarkhani,
	kvm, linux-hardening, linux-hyperv, linux-kernel,
	linux-security-module, linux-um, x86

On Sat, Mar 23, 2024 at 03:37:21PM +0800, David Gow wrote:
> On Tue, 19 Mar 2024 at 18:49, Mickaël Salaün <mic@digikod.net> wrote:
> >
> > Previously, when a kernel test thread crashed (e.g. NULL pointer
> > dereference, general protection fault), the KUnit test hanged for 30
> > seconds and exited with a timeout error.
> >
> > Fix this issue by waiting on task_struct->vfork_done instead of the
> > custom kunit_try_catch.try_completion, and track the execution state by
> > initially setting try_result with -EINTR and only setting it to 0 if
> > the test passed.
> >
> > Fix kunit_generic_run_threadfn_adapter() signature by returning 0
> > instead of calling kthread_complete_and_exit().  Because thread's exit
> > code is never checked, always set it to 0 to make it clear.
> >
> > Fix the -EINTR error message, which couldn't be reached until now.
> >
> > This is tested with a following patch.
> >
> > Cc: Brendan Higgins <brendanhiggins@google.com>
> > Cc: Shuah Khan <skhan@linuxfoundation.org>
> > Reviewed-by: Kees Cook <keescook@chromium.org>
> > Reviewed-by: David Gow <davidgow@google.com>
> > Tested-by: Rae Moar <rmoar@google.com>
> > Signed-off-by: Mickaël Salaün <mic@digikod.net>
> > Link: https://lore.kernel.org/r/20240319104857.70783-5-mic@digikod.net
> > ---
> >
> > Changes since v2:
> > * s/-EFAULT/-EINTR/ in commit message as spotted by Rae.
> > * Add a comment explaining vfork_done as suggested by David.
> > * Add David's Reviewed-by.
> > * Add Rae's Tested-by.
> >
> > Changes since v1:
> > * Add Kees's Reviewed-by.
> > ---
> >  include/kunit/try-catch.h |  3 ---
> >  lib/kunit/try-catch.c     | 19 ++++++++++++-------
> >  2 files changed, 12 insertions(+), 10 deletions(-)
> >
> > diff --git a/include/kunit/try-catch.h b/include/kunit/try-catch.h
> > index c507dd43119d..7c966a1adbd3 100644
> > --- a/include/kunit/try-catch.h
> > +++ b/include/kunit/try-catch.h
> > @@ -14,13 +14,11 @@
> >
> >  typedef void (*kunit_try_catch_func_t)(void *);
> >
> > -struct completion;
> >  struct kunit;
> >
> >  /**
> >   * struct kunit_try_catch - provides a generic way to run code which might fail.
> >   * @test: The test case that is currently being executed.
> > - * @try_completion: Completion that the control thread waits on while test runs.
> >   * @try_result: Contains any errno obtained while running test case.
> >   * @try: The function, the test case, to attempt to run.
> >   * @catch: The function called if @try bails out.
> > @@ -46,7 +44,6 @@ struct kunit;
> >  struct kunit_try_catch {
> >         /* private: internal use only. */
> >         struct kunit *test;
> > -       struct completion *try_completion;
> >         int try_result;
> >         kunit_try_catch_func_t try;
> >         kunit_try_catch_func_t catch;
> > diff --git a/lib/kunit/try-catch.c b/lib/kunit/try-catch.c
> > index cab8b24b5d5a..7a3910dd78a6 100644
> > --- a/lib/kunit/try-catch.c
> > +++ b/lib/kunit/try-catch.c
> > @@ -18,7 +18,7 @@
> >  void __noreturn kunit_try_catch_throw(struct kunit_try_catch *try_catch)
> >  {
> >         try_catch->try_result = -EFAULT;
> > -       kthread_complete_and_exit(try_catch->try_completion, -EFAULT);
> > +       kthread_exit(0);
> 
> It turns out kthread_exit() is not exported, so this doesn't work if
> KUnit is built as a module.
> 
> I think the options we have are:
> - Add EXPORT_SYMBOL(kthread_exit).

I'll go this way. This should not be an issue because
kthread_complete_and_exit() can already (only) call kthread_exit() if
the completion is NULL, but directly calling kthread_exit() is cleaner.

> - Keep using out own completion, and kthread_complete_and_exit()
> - try_get_module() before spawning the thread, and use
> module_put_and_kthread_exit().
> 
> I think all of these would be okay, but I could've missed something.
> 
> -- David

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 7/7] kunit: Add tests for fault
  2024-03-19 10:48 ` [PATCH v3 7/7] kunit: Add tests for fault Mickaël Salaün
@ 2024-04-19 22:33   ` Guenter Roeck
  2024-04-19 23:38     ` Guenter Roeck
  0 siblings, 1 reply; 15+ messages in thread
From: Guenter Roeck @ 2024-04-19 22:33 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: Brendan Higgins, David Gow, Rae Moar, Shuah Khan, Alan Maguire,
	Borislav Petkov, Dave Hansen, H . Peter Anvin, Ingo Molnar,
	James Morris, Kees Cook, Luis Chamberlain,
	Madhavan T . Venkataraman, Marco Pagani, Paolo Bonzini,
	Sean Christopherson, Stephen Boyd, Thara Gopinath,
	Thomas Gleixner, Vitaly Kuznetsov, Wanpeng Li, Zahra Tarkhani,
	kvm, linux-hardening, linux-hyperv, linux-kernel,
	linux-security-module, linux-um, x86

Hi,

On Tue, Mar 19, 2024 at 11:48:57AM +0100, Mickaël Salaün wrote:
> Add a test case to check NULL pointer dereference and make sure it would
> result as a failed test.
> 
> The full kunit_fault test suite is marked as skipped when run on UML
> because it would result to a kernel panic.
> 
> Tested with:
> ./tools/testing/kunit/kunit.py run --arch x86_64 kunit_fault
> ./tools/testing/kunit/kunit.py run --arch arm64 \
>   --cross_compile=aarch64-linux-gnu- kunit_fault
> 

What is the rationale for adding those tests unconditionally whenever
CONFIG_KUNIT_TEST is enabled ? This completely messes up my test system
because it concludes that it is pointless to continue testing
after the "Unable to handle kernel NULL pointer dereference" backtrace.
At the same time, it is all or nothing, meaning I can not disable
it but still run other kunit tests.

Guenter

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 7/7] kunit: Add tests for fault
  2024-04-19 22:33   ` Guenter Roeck
@ 2024-04-19 23:38     ` Guenter Roeck
  2024-04-22 13:08       ` Mickaël Salaün
  0 siblings, 1 reply; 15+ messages in thread
From: Guenter Roeck @ 2024-04-19 23:38 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: Brendan Higgins, David Gow, Rae Moar, Shuah Khan, Alan Maguire,
	Borislav Petkov, Dave Hansen, H . Peter Anvin, Ingo Molnar,
	James Morris, Kees Cook, Luis Chamberlain,
	Madhavan T . Venkataraman, Marco Pagani, Paolo Bonzini,
	Sean Christopherson, Stephen Boyd, Thara Gopinath,
	Thomas Gleixner, Vitaly Kuznetsov, Wanpeng Li, Zahra Tarkhani,
	kvm, linux-hardening, linux-hyperv, linux-kernel,
	linux-security-module, linux-um, x86

On Fri, Apr 19, 2024 at 03:33:49PM -0700, Guenter Roeck wrote:
> Hi,
> 
> On Tue, Mar 19, 2024 at 11:48:57AM +0100, Mickaël Salaün wrote:
> > Add a test case to check NULL pointer dereference and make sure it would
> > result as a failed test.
> > 
> > The full kunit_fault test suite is marked as skipped when run on UML
> > because it would result to a kernel panic.
> > 
> > Tested with:
> > ./tools/testing/kunit/kunit.py run --arch x86_64 kunit_fault
> > ./tools/testing/kunit/kunit.py run --arch arm64 \
> >   --cross_compile=aarch64-linux-gnu- kunit_fault
> > 
> 
> What is the rationale for adding those tests unconditionally whenever
> CONFIG_KUNIT_TEST is enabled ? This completely messes up my test system
> because it concludes that it is pointless to continue testing
> after the "Unable to handle kernel NULL pointer dereference" backtrace.
> At the same time, it is all or nothing, meaning I can not disable
> it but still run other kunit tests.
> 

Oh, never mind. I just disabled CONFIG_KUNIT_TEST in my test bed
to "solve" the problem. I'll take that as one of those "unintended
consequences" items: Instead of more tests, there are fewer.

Guenter

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 7/7] kunit: Add tests for fault
  2024-04-19 23:38     ` Guenter Roeck
@ 2024-04-22 13:08       ` Mickaël Salaün
  2024-04-22 13:35         ` Guenter Roeck
  0 siblings, 1 reply; 15+ messages in thread
From: Mickaël Salaün @ 2024-04-22 13:08 UTC (permalink / raw)
  To: Guenter Roeck, David Gow
  Cc: Brendan Higgins, Rae Moar, Shuah Khan, Alan Maguire,
	Borislav Petkov, Dave Hansen, H . Peter Anvin, Ingo Molnar,
	James Morris, Kees Cook, Luis Chamberlain,
	Madhavan T . Venkataraman, Marco Pagani, Paolo Bonzini,
	Sean Christopherson, Stephen Boyd, Thara Gopinath,
	Thomas Gleixner, Vitaly Kuznetsov, Wanpeng Li, Zahra Tarkhani,
	kvm, linux-hardening, linux-hyperv, linux-kernel,
	linux-security-module, linux-um, x86

On Fri, Apr 19, 2024 at 04:38:01PM -0700, Guenter Roeck wrote:
> On Fri, Apr 19, 2024 at 03:33:49PM -0700, Guenter Roeck wrote:
> > Hi,
> > 
> > On Tue, Mar 19, 2024 at 11:48:57AM +0100, Mickaël Salaün wrote:
> > > Add a test case to check NULL pointer dereference and make sure it would
> > > result as a failed test.
> > > 
> > > The full kunit_fault test suite is marked as skipped when run on UML
> > > because it would result to a kernel panic.
> > > 
> > > Tested with:
> > > ./tools/testing/kunit/kunit.py run --arch x86_64 kunit_fault
> > > ./tools/testing/kunit/kunit.py run --arch arm64 \
> > >   --cross_compile=aarch64-linux-gnu- kunit_fault
> > > 
> > 
> > What is the rationale for adding those tests unconditionally whenever
> > CONFIG_KUNIT_TEST is enabled ? This completely messes up my test system
> > because it concludes that it is pointless to continue testing
> > after the "Unable to handle kernel NULL pointer dereference" backtrace.
> > At the same time, it is all or nothing, meaning I can not disable
> > it but still run other kunit tests.
> > 

CONFIG_KUNIT_TEST is to test KUnit itself.  Why does this messes up your
test system, and what is your test system?  Is it related to the kernel
warning and then the message you previously sent?
https://lore.kernel.org/r/fd604ae0-5630-4745-acf2-1e51c69cf0c0@roeck-us.net
It seems David has a solution to suppress such warning.

> 
> Oh, never mind. I just disabled CONFIG_KUNIT_TEST in my test bed
> to "solve" the problem. I'll take that as one of those "unintended
> consequences" items: Instead of more tests, there are fewer.
> 
> Guenter
> 

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 7/7] kunit: Add tests for fault
  2024-04-22 13:08       ` Mickaël Salaün
@ 2024-04-22 13:35         ` Guenter Roeck
  2024-04-23  9:22           ` David Gow
  0 siblings, 1 reply; 15+ messages in thread
From: Guenter Roeck @ 2024-04-22 13:35 UTC (permalink / raw)
  To: Mickaël Salaün, David Gow
  Cc: Brendan Higgins, Rae Moar, Shuah Khan, Alan Maguire,
	Borislav Petkov, Dave Hansen, H . Peter Anvin, Ingo Molnar,
	James Morris, Kees Cook, Luis Chamberlain,
	Madhavan T . Venkataraman, Marco Pagani, Paolo Bonzini,
	Sean Christopherson, Stephen Boyd, Thara Gopinath,
	Thomas Gleixner, Vitaly Kuznetsov, Wanpeng Li, Zahra Tarkhani,
	kvm, linux-hardening, linux-hyperv, linux-kernel,
	linux-security-module, linux-um, x86

On 4/22/24 06:08, Mickaël Salaün wrote:
> On Fri, Apr 19, 2024 at 04:38:01PM -0700, Guenter Roeck wrote:
>> On Fri, Apr 19, 2024 at 03:33:49PM -0700, Guenter Roeck wrote:
>>> Hi,
>>>
>>> On Tue, Mar 19, 2024 at 11:48:57AM +0100, Mickaël Salaün wrote:
>>>> Add a test case to check NULL pointer dereference and make sure it would
>>>> result as a failed test.
>>>>
>>>> The full kunit_fault test suite is marked as skipped when run on UML
>>>> because it would result to a kernel panic.
>>>>
>>>> Tested with:
>>>> ./tools/testing/kunit/kunit.py run --arch x86_64 kunit_fault
>>>> ./tools/testing/kunit/kunit.py run --arch arm64 \
>>>>    --cross_compile=aarch64-linux-gnu- kunit_fault
>>>>
>>>
>>> What is the rationale for adding those tests unconditionally whenever
>>> CONFIG_KUNIT_TEST is enabled ? This completely messes up my test system
>>> because it concludes that it is pointless to continue testing
>>> after the "Unable to handle kernel NULL pointer dereference" backtrace.
>>> At the same time, it is all or nothing, meaning I can not disable
>>> it but still run other kunit tests.
>>>
> 
> CONFIG_KUNIT_TEST is to test KUnit itself.  Why does this messes up your
> test system, and what is your test system?  Is it related to the kernel
> warning and then the message you previously sent?

It is not a warning, it is a BUG which terminates the affected kernel thread.
NULL pointer dereferences are normally fatal, which is why I abort tests
if one is encountered. I am not going to start introducing code into my
scripts to ignore such warnings (or BUG messages) on a case by case basis;
this would be unmaintainable.

> https://lore.kernel.org/r/fd604ae0-5630-4745-acf2-1e51c69cf0c0@roeck-us.net
> It seems David has a solution to suppress such warning.
> 

I don't think so. My series tried to suppress warning backtraces, not BUG
messages. BUG messages can not easily be suppressed since the reaction is
architecture specific and typically fatal.

As I said below, never mind, I just disabled CONFIG_KUNIT_TEST in my testing.

Guenter

>>
>> Oh, never mind. I just disabled CONFIG_KUNIT_TEST in my test bed
>> to "solve" the problem. I'll take that as one of those "unintended
>> consequences" items: Instead of more tests, there are fewer.
>>
>> Guenter
>>


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v3 7/7] kunit: Add tests for fault
  2024-04-22 13:35         ` Guenter Roeck
@ 2024-04-23  9:22           ` David Gow
  0 siblings, 0 replies; 15+ messages in thread
From: David Gow @ 2024-04-23  9:22 UTC (permalink / raw)
  To: Guenter Roeck
  Cc: Mickaël Salaün, Brendan Higgins, Rae Moar, Shuah Khan,
	Alan Maguire, Borislav Petkov, Dave Hansen, H . Peter Anvin,
	Ingo Molnar, James Morris, Kees Cook, Luis Chamberlain,
	Madhavan T . Venkataraman, Marco Pagani, Paolo Bonzini,
	Sean Christopherson, Stephen Boyd, Thara Gopinath,
	Thomas Gleixner, Vitaly Kuznetsov, Wanpeng Li, Zahra Tarkhani,
	kvm, linux-hardening, linux-hyperv, linux-kernel,
	linux-security-module, linux-um, x86

[-- Attachment #1: Type: text/plain, Size: 2914 bytes --]

On Mon, 22 Apr 2024 at 21:36, Guenter Roeck <linux@roeck-us.net> wrote:
>
> On 4/22/24 06:08, Mickaël Salaün wrote:
> > On Fri, Apr 19, 2024 at 04:38:01PM -0700, Guenter Roeck wrote:
> >> On Fri, Apr 19, 2024 at 03:33:49PM -0700, Guenter Roeck wrote:
> >>> Hi,
> >>>
> >>> On Tue, Mar 19, 2024 at 11:48:57AM +0100, Mickaël Salaün wrote:
> >>>> Add a test case to check NULL pointer dereference and make sure it would
> >>>> result as a failed test.
> >>>>
> >>>> The full kunit_fault test suite is marked as skipped when run on UML
> >>>> because it would result to a kernel panic.
> >>>>
> >>>> Tested with:
> >>>> ./tools/testing/kunit/kunit.py run --arch x86_64 kunit_fault
> >>>> ./tools/testing/kunit/kunit.py run --arch arm64 \
> >>>>    --cross_compile=aarch64-linux-gnu- kunit_fault
> >>>>
> >>>
> >>> What is the rationale for adding those tests unconditionally whenever
> >>> CONFIG_KUNIT_TEST is enabled ? This completely messes up my test system
> >>> because it concludes that it is pointless to continue testing
> >>> after the "Unable to handle kernel NULL pointer dereference" backtrace.
> >>> At the same time, it is all or nothing, meaning I can not disable
> >>> it but still run other kunit tests.
> >>>
> >
> > CONFIG_KUNIT_TEST is to test KUnit itself.  Why does this messes up your
> > test system, and what is your test system?  Is it related to the kernel
> > warning and then the message you previously sent?
>
> It is not a warning, it is a BUG which terminates the affected kernel thread.
> NULL pointer dereferences are normally fatal, which is why I abort tests
> if one is encountered. I am not going to start introducing code into my
> scripts to ignore such warnings (or BUG messages) on a case by case basis;
> this would be unmaintainable.
>
> > https://lore.kernel.org/r/fd604ae0-5630-4745-acf2-1e51c69cf0c0@roeck-us.net
> > It seems David has a solution to suppress such warning.
> >
>
> I don't think so. My series tried to suppress warning backtraces, not BUG
> messages. BUG messages can not easily be suppressed since the reaction is
> architecture specific and typically fatal.
>
> As I said below, never mind, I just disabled CONFIG_KUNIT_TEST in my testing.
>
> Guenter
>

I think it probably makes sense to permit disabling the fault tests
independently, at least until we have a way of suppressing the
warnings.

I've sent out a patch to add a CONFIG_KUNIT_FAULT_TEST option to
disable these tests. Would that help?
https://lore.kernel.org/linux-kselftest/20240423090808.242389-1-davidgow@google.com/

(The other option is to split the tests out into a totally separate
file / module. I think that's an option (and would make the config
option more consistent with other test options) but since they're
otherwise part of the KUnit tests, I think I prefer to keep them
together.)

Cheers,
-- David

[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4014 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2024-04-23  9:22 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-03-19 10:48 [PATCH v3 0/7] Handle faults in KUnit tests Mickaël Salaün
2024-03-19 10:48 ` [PATCH v3 1/7] kunit: Handle thread creation error Mickaël Salaün
2024-03-19 10:48 ` [PATCH v3 2/7] kunit: Fix kthread reference Mickaël Salaün
2024-03-19 10:48 ` [PATCH v3 3/7] kunit: Fix timeout message Mickaël Salaün
2024-03-19 10:48 ` [PATCH v3 4/7] kunit: Handle test faults Mickaël Salaün
2024-03-23  7:37   ` David Gow
2024-03-26  9:02     ` Mickaël Salaün
2024-03-19 10:48 ` [PATCH v3 5/7] kunit: Fix KUNIT_SUCCESS() calls in iov_iter tests Mickaël Salaün
2024-03-19 10:48 ` [PATCH v3 6/7] kunit: Print last test location on fault Mickaël Salaün
2024-03-19 10:48 ` [PATCH v3 7/7] kunit: Add tests for fault Mickaël Salaün
2024-04-19 22:33   ` Guenter Roeck
2024-04-19 23:38     ` Guenter Roeck
2024-04-22 13:08       ` Mickaël Salaün
2024-04-22 13:35         ` Guenter Roeck
2024-04-23  9:22           ` David Gow

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).