Message ID | 20240229170409.365386-9-mic@digikod.net (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Run KUnit tests late and handle faults | expand |
On Thu, Feb 29, 2024 at 06:04:09PM +0100, Mickaël Salaün wrote: > The first test checks NULL pointer dereference and make sure it would > result as a failed test. > > The second and third tests check that read-only data is indeed read-only > and trying to modify it would result as a failed test. > > This kunit_x86_fault test suite is marked as skipped when run on a > non-x86 native architecture. It is then skipped on UML because such > test would result to a kernel panic. > > Tested with: > ./tools/testing/kunit/kunit.py run --arch x86_64 kunit_x86_fault > > Cc: Brendan Higgins <brendanhiggins@google.com> > Cc: David Gow <davidgow@google.com> > Cc: Rae Moar <rmoar@google.com> > Cc: Shuah Khan <skhan@linuxfoundation.org> > Signed-off-by: Mickaël Salaün <mic@digikod.net> If we can add some way to collect WARN/BUG output for examination, I could rewrite most of LKDTM in KUnit! I really like this! > --- > lib/kunit/kunit-test.c | 115 ++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 114 insertions(+), 1 deletion(-) > > diff --git a/lib/kunit/kunit-test.c b/lib/kunit/kunit-test.c > index f7980ef236a3..57d8eff00c66 100644 > --- a/lib/kunit/kunit-test.c > +++ b/lib/kunit/kunit-test.c > @@ -10,6 +10,7 @@ > #include <kunit/test-bug.h> > > #include <linux/device.h> > +#include <linux/init.h> > #include <kunit/device.h> > > #include "string-stream.h" > @@ -109,6 +110,117 @@ static struct kunit_suite kunit_try_catch_test_suite = { > .test_cases = kunit_try_catch_test_cases, > }; > > +#ifdef CONFIG_X86 Why is this x86 specific?
On Thu, Feb 29, 2024 at 10:28:18AM -0800, Kees Cook wrote: > On Thu, Feb 29, 2024 at 06:04:09PM +0100, Mickaël Salaün wrote: > > The first test checks NULL pointer dereference and make sure it would > > result as a failed test. > > > > The second and third tests check that read-only data is indeed read-only > > and trying to modify it would result as a failed test. > > > > This kunit_x86_fault test suite is marked as skipped when run on a > > non-x86 native architecture. It is then skipped on UML because such > > test would result to a kernel panic. > > > > Tested with: > > ./tools/testing/kunit/kunit.py run --arch x86_64 kunit_x86_fault > > > > Cc: Brendan Higgins <brendanhiggins@google.com> > > Cc: David Gow <davidgow@google.com> > > Cc: Rae Moar <rmoar@google.com> > > Cc: Shuah Khan <skhan@linuxfoundation.org> > > Signed-off-by: Mickaël Salaün <mic@digikod.net> > > If we can add some way to collect WARN/BUG output for examination, I > could rewrite most of LKDTM in KUnit! I really like this! Thanks! About the WARN/BUG examination, I guess the easier way would be to do in in user space by extending kunit_parser.py. > > > --- > > lib/kunit/kunit-test.c | 115 ++++++++++++++++++++++++++++++++++++++++- > > 1 file changed, 114 insertions(+), 1 deletion(-) > > > > diff --git a/lib/kunit/kunit-test.c b/lib/kunit/kunit-test.c > > index f7980ef236a3..57d8eff00c66 100644 > > --- a/lib/kunit/kunit-test.c > > +++ b/lib/kunit/kunit-test.c > > @@ -10,6 +10,7 @@ > > #include <kunit/test-bug.h> > > > > #include <linux/device.h> > > +#include <linux/init.h> > > #include <kunit/device.h> > > > > #include "string-stream.h" > > @@ -109,6 +110,117 @@ static struct kunit_suite kunit_try_catch_test_suite = { > > .test_cases = kunit_try_catch_test_cases, > > }; > > > > +#ifdef CONFIG_X86 > > Why is this x86 specific? Because I didn't test on other architecture, and it looks it crashed on arm64. :) I'll test on arm64 and change this condition with !CONFIG_UML. > > -- > Kees Cook >
Hi Mickaël, kernel test robot noticed the following build warnings: [auto build test WARNING on d206a76d7d2726f3b096037f2079ce0bd3ba329b] url: https://github.com/intel-lab-lkp/linux/commits/Micka-l-Sala-n/kunit-Run-tests-when-the-kernel-is-fully-setup/20240301-011020 base: d206a76d7d2726f3b096037f2079ce0bd3ba329b patch link: https://lore.kernel.org/r/20240229170409.365386-9-mic%40digikod.net patch subject: [PATCH v1 8/8] kunit: Add tests for faults config: x86_64-randconfig-122-20240301 (https://download.01.org/0day-ci/archive/20240302/202403020418.NnNnFElm-lkp@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240302/202403020418.NnNnFElm-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202403020418.NnNnFElm-lkp@intel.com/ sparse warnings: (new ones prefixed by >>) >> lib/kunit/kunit-test.c:142:11: sparse: sparse: symbol 'test_const' was not declared. Should it be static? vim +/test_const +142 lib/kunit/kunit-test.c 141 > 142 const int test_const = 1; 143
diff --git a/lib/kunit/kunit-test.c b/lib/kunit/kunit-test.c index f7980ef236a3..57d8eff00c66 100644 --- a/lib/kunit/kunit-test.c +++ b/lib/kunit/kunit-test.c @@ -10,6 +10,7 @@ #include <kunit/test-bug.h> #include <linux/device.h> +#include <linux/init.h> #include <kunit/device.h> #include "string-stream.h" @@ -109,6 +110,117 @@ static struct kunit_suite kunit_try_catch_test_suite = { .test_cases = kunit_try_catch_test_cases, }; +#ifdef CONFIG_X86 + +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); +} + +#if defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_STRICT_MODULE_RWX) + +const int test_const = 1; + +static void kunit_test_const(void *data) +{ + struct kunit *test = data; + /* Bypasses compiler check. */ + int *ptr = (int *)&test_const; + + KUNIT_EXPECT_EQ(test, test_const, 1); + *ptr = 2; + + KUNIT_FAIL(test, "This line should never be reached\n"); +} + +static void kunit_test_fault_const(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_const, + kunit_test_catch); + kunit_try_catch_run(try_catch, test); + + KUNIT_EXPECT_EQ(test, test_const, 1); + KUNIT_EXPECT_EQ(test, try_catch->try_result, -EINTR); + KUNIT_EXPECT_TRUE(test, ctx->function_called); +} + +static int test_rodata __ro_after_init = 1; + +static void kunit_test_rodata(void *data) +{ + struct kunit *test = data; + + KUNIT_EXPECT_EQ(test, test_rodata, 1); + test_rodata = 2; + + KUNIT_FAIL(test, "This line should never be reached\n"); +} + +static void kunit_test_fault_rodata(struct kunit *test) +{ + struct kunit_try_catch_test_context *ctx = test->priv; + struct kunit_try_catch *try_catch = ctx->try_catch; + + if (!rodata_enabled) + kunit_skip(test, "Strict RWX is not enabled"); + + kunit_try_catch_init(try_catch, test, kunit_test_rodata, + kunit_test_catch); + kunit_try_catch_run(try_catch, test); + + KUNIT_EXPECT_EQ(test, test_rodata, 1); + KUNIT_EXPECT_EQ(test, try_catch->try_result, -EINTR); + KUNIT_EXPECT_TRUE(test, ctx->function_called); +} + +#else /* defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_STRICT_MODULE_RWX) */ + +static void kunit_test_fault_rodata(struct kunit *test) +{ + kunit_skip(test, "Strict RWX is not supported"); +} + +#endif /* defined(CONFIG_STRICT_KERNEL_RWX) || defined(CONFIG_STRICT_MODULE_RWX) */ +#endif /* CONFIG_X86 */ + +static struct kunit_case kunit_x86_fault_test_cases[] = { +#ifdef CONFIG_X86 + KUNIT_CASE(kunit_test_fault_null_dereference), + KUNIT_CASE(kunit_test_fault_const), + KUNIT_CASE(kunit_test_fault_rodata), +#endif /* CONFIG_X86 */ + {} +}; + +static struct kunit_suite kunit_x86_fault_test_suite = { + .name = "kunit_x86_fault", + .init = kunit_try_catch_test_init, + .test_cases = kunit_x86_fault_test_cases, +}; + /* * Context for testing test managed resources * is_resource_initialized is used to test arbitrary resources @@ -826,6 +938,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_x86_fault_test_suite); MODULE_LICENSE("GPL v2");
The first test checks NULL pointer dereference and make sure it would result as a failed test. The second and third tests check that read-only data is indeed read-only and trying to modify it would result as a failed test. This kunit_x86_fault test suite is marked as skipped when run on a non-x86 native architecture. It is then skipped on UML because such test would result to a kernel panic. Tested with: ./tools/testing/kunit/kunit.py run --arch x86_64 kunit_x86_fault Cc: Brendan Higgins <brendanhiggins@google.com> Cc: David Gow <davidgow@google.com> Cc: Rae Moar <rmoar@google.com> Cc: Shuah Khan <skhan@linuxfoundation.org> Signed-off-by: Mickaël Salaün <mic@digikod.net> --- lib/kunit/kunit-test.c | 115 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 114 insertions(+), 1 deletion(-)