From patchwork Thu Feb 29 17:04:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= X-Patchwork-Id: 13577456 Received: from smtp-190a.mail.infomaniak.ch (smtp-190a.mail.infomaniak.ch [185.125.25.10]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6E67D4AECA for ; Thu, 29 Feb 2024 17:04:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.125.25.10 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709226277; cv=none; b=ebV6JN/Q46S24X+BYAn7NMEx19yrf+hAIin5GZtfp17JJsPdxVsq+Nt6n6uXV8eKDuHyeZm/58fqgGxPmha/MqxmGm2XVq0Ovy7xE08rrRe0C2CCuqEG/RujKlp0x33wSFwrwkI66Wb1VWNzWOoYZYuEHQrRW6ae7dzCVnJ5l90= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709226277; c=relaxed/simple; bh=DlAsxEK3tQlg4LhdX34U1CnfGpSuxy5oYOamwDNbGFY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=B68F9rNG6S/p7cI5qO/kDD1Lad1GE1w9mhYGE4BM97tym1HJfZ1qSsPEGRPqvU4H2P1aamO1hJICdhXywXpiZ/0325MudFey3dE7QZ07QMUJeJMUnLPPNcCLoZxOU0HrdT3GpZuYwQ0MTrEEfSjo3r3rI7JEue0smrqTtHavAYA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=digikod.net; spf=pass smtp.mailfrom=digikod.net; dkim=pass (1024-bit key) header.d=digikod.net header.i=@digikod.net header.b=QP2PFlub; arc=none smtp.client-ip=185.125.25.10 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=digikod.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=digikod.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=digikod.net header.i=@digikod.net header.b="QP2PFlub" Received: from smtp-3-0001.mail.infomaniak.ch (unknown [10.4.36.108]) by smtp-3-3000.mail.infomaniak.ch (Postfix) with ESMTPS id 4TlyHr2DgkzMrkv4; Thu, 29 Feb 2024 18:04:24 +0100 (CET) Received: from unknown by smtp-3-0001.mail.infomaniak.ch (Postfix) with ESMTPA id 4TlyHq2frXzMppV9; Thu, 29 Feb 2024 18:04:23 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=digikod.net; s=20191114; t=1709226264; bh=DlAsxEK3tQlg4LhdX34U1CnfGpSuxy5oYOamwDNbGFY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QP2PFlubN8YS3DtbVYcaoZ7F8AEJxRVj/ZpidDwtMIxaPE9wvRlOFCyQKZLXjHlfb CwrIBwpO8o/nJdw3spjb1cokWwJIee25cbRMlTuKY37pX91jsl5JyD6WP/Ux046HA8 qPZwQA5njQzSlLKLklDVhs7ZoVh6mWFR2vzqJPUk= From: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= To: Brendan Higgins , David Gow , Kees Cook , Rae Moar , Shuah Khan Cc: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= , Alan Maguire , Borislav Petkov , Dave Hansen , "H . Peter Anvin" , Ingo Molnar , James Morris , Luis Chamberlain , "Madhavan T . Venkataraman" , Marco Pagani , Paolo Bonzini , Sean Christopherson , Stephen Boyd , Thara Gopinath , Thomas Gleixner , Vitaly Kuznetsov , Wanpeng Li , Zahra Tarkhani , kvm@vger.kernel.org, linux-hardening@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, linux-um@lists.infradead.org, x86@kernel.org Subject: [PATCH v1 1/8] kunit: Run tests when the kernel is fully setup Date: Thu, 29 Feb 2024 18:04:02 +0100 Message-ID: <20240229170409.365386-2-mic@digikod.net> In-Reply-To: <20240229170409.365386-1-mic@digikod.net> References: <20240229170409.365386-1-mic@digikod.net> Precedence: bulk X-Mailing-List: linux-hardening@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Infomaniak-Routing: alpha Run all the KUnit tests just before the first userspace code is launched. This makes it it possible to write new tests that check the kernel in its final state i.e., with all async __init code called, memory and RCU properly set up, and sysctl boot arguments evaluated. The initial motivation is to run hardening tests (e.g. memory protection, Heki's CR-pinning), which require such security protection to be fully setup (e.g. memory marked as read-only). Because the suite set could refer to init data, initialize the suite set with late_initcall(), before kunit_run_all_tests(), if KUnit is built-in and enabled at boot time. To make it more consistent and easier to manage, whatever filters are used or not, always copy test suite entries and free them after all tests are run. Because of the prepare_namespace() call, we need to have a valid root filesystem. To make it simple, let's use tmpfs with an empty root. Teach kunit_kernel.py:LinuxSourceTreeOperations*() about the related kernel boot argument, and add this filesystem to the kunit.py's kernel build requirements. Remove __init and __refdata markers from iov_iter, bitfield, checksum, and the example KUnit tests. Without this change, the kernel tries to execute NX-protected pages (because the pages are deallocated). Tested with: ./tools/testing/kunit/kunit.py run --alltests ./tools/testing/kunit/kunit.py run --alltests --arch x86_64 Cc: Alan Maguire Cc: Brendan Higgins Cc: David Gow Cc: Kees Cook Cc: Luis Chamberlain Cc: Marco Pagani Cc: Rae Moar Cc: Shuah Khan Cc: Stephen Boyd Signed-off-by: Mickaël Salaün --- init/main.c | 4 +- lib/bitfield_kunit.c | 8 +-- lib/checksum_kunit.c | 2 +- lib/kunit/executor.c | 81 +++++++++++++++++++++-------- lib/kunit/kunit-example-test.c | 6 +-- lib/kunit_iov_iter.c | 52 +++++++++--------- tools/testing/kunit/kunit_kernel.py | 6 ++- 7 files changed, 96 insertions(+), 63 deletions(-) diff --git a/init/main.c b/init/main.c index e24b0780fdff..b39d74727aad 100644 --- a/init/main.c +++ b/init/main.c @@ -1463,6 +1463,8 @@ static int __ref kernel_init(void *unused) do_sysctl_args(); + kunit_run_all_tests(); + if (ramdisk_execute_command) { ret = run_init_process(ramdisk_execute_command); if (!ret) @@ -1550,8 +1552,6 @@ static noinline void __init kernel_init_freeable(void) do_basic_setup(); - kunit_run_all_tests(); - wait_for_initramfs(); console_on_rootfs(); diff --git a/lib/bitfield_kunit.c b/lib/bitfield_kunit.c index 1473d8b4bf0f..71e9f2e96496 100644 --- a/lib/bitfield_kunit.c +++ b/lib/bitfield_kunit.c @@ -57,7 +57,7 @@ CHECK_ENC_GET_BE(tp, v, field, res); \ } while (0) -static void __init test_bitfields_constants(struct kunit *context) +static void test_bitfields_constants(struct kunit *context) { /* * NOTE @@ -100,7 +100,7 @@ static void __init test_bitfields_constants(struct kunit *context) tp##_encode_bits(v, mask) != v << __ffs64(mask));\ } while (0) -static void __init test_bitfields_variables(struct kunit *context) +static void test_bitfields_variables(struct kunit *context) { CHECK(u8, 0x0f); CHECK(u8, 0xf0); @@ -126,7 +126,7 @@ static void __init test_bitfields_variables(struct kunit *context) } #ifdef TEST_BITFIELD_COMPILE -static void __init test_bitfields_compile(struct kunit *context) +static void test_bitfields_compile(struct kunit *context) { /* these should fail compilation */ CHECK_ENC_GET(16, 16, 0x0f00, 0x1000); @@ -137,7 +137,7 @@ static void __init test_bitfields_compile(struct kunit *context) } #endif -static struct kunit_case __refdata bitfields_test_cases[] = { +static struct kunit_case bitfields_test_cases[] = { KUNIT_CASE(test_bitfields_constants), KUNIT_CASE(test_bitfields_variables), {} diff --git a/lib/checksum_kunit.c b/lib/checksum_kunit.c index 225bb7701460..41aaed3a4963 100644 --- a/lib/checksum_kunit.c +++ b/lib/checksum_kunit.c @@ -620,7 +620,7 @@ static void test_csum_ipv6_magic(struct kunit *test) #endif /* !CONFIG_NET */ } -static struct kunit_case __refdata checksum_test_cases[] = { +static struct kunit_case checksum_test_cases[] = { KUNIT_CASE(test_csum_fixed_random_inputs), KUNIT_CASE(test_csum_all_carry_inputs), KUNIT_CASE(test_csum_no_carry_inputs), diff --git a/lib/kunit/executor.c b/lib/kunit/executor.c index 689fff2b2b10..ff3e66ffa739 100644 --- a/lib/kunit/executor.c +++ b/lib/kunit/executor.c @@ -15,6 +15,8 @@ extern struct kunit_suite * const __kunit_suites_end[]; extern struct kunit_suite * const __kunit_init_suites_start[]; extern struct kunit_suite * const __kunit_init_suites_end[]; +static struct kunit_suite_set final_suite_set = {}; + static char *action_param; module_param_named(action, action_param, charp, 0400); @@ -233,6 +235,21 @@ kunit_filter_suites(const struct kunit_suite_set *suite_set, if (!filtered_suite) continue; + if (filtered_suite == suite_set->start[i]) { + /* + * To make memory allocation consistent whatever + * filters are used or not, and to keep + * kunit_free_suite_set() simple, always copy static + * data. + */ + filtered_suite = kmemdup(filtered_suite, sizeof(*filtered_suite), + GFP_KERNEL); + if (!filtered_suite) { + *err = -ENOMEM; + goto free_parsed_filters; + } + } + *copy++ = filtered_suite; } filtered.start = copy_start; @@ -348,7 +365,7 @@ static void kunit_handle_shutdown(void) } -int kunit_run_all_tests(void) +static int kunit_init_suites(void) { struct kunit_suite_set suite_set = {NULL, NULL}; struct kunit_suite_set filtered_suite_set = {NULL, NULL}; @@ -361,6 +378,9 @@ int kunit_run_all_tests(void) size_t init_num_suites = init_suite_set.end - init_suite_set.start; int err = 0; + if (!kunit_enabled()) + return 0; + if (init_num_suites > 0) { suite_set = kunit_merge_suite_sets(init_suite_set, normal_suite_set); if (!suite_set.start) @@ -368,41 +388,56 @@ int kunit_run_all_tests(void) } else suite_set = normal_suite_set; - if (!kunit_enabled()) { - pr_info("kunit: disabled\n"); + filtered_suite_set = kunit_filter_suites(&suite_set, filter_glob_param, + filter_param, filter_action_param, &err); + + /* Free original suite set before using filtered suite set */ + if (init_num_suites > 0) + kfree(suite_set.start); + suite_set = filtered_suite_set; + + if (err) { + pr_err("kunit executor: error filtering suites: %d\n", err); goto free_out; } - if (filter_glob_param || filter_param) { - filtered_suite_set = kunit_filter_suites(&suite_set, filter_glob_param, - filter_param, filter_action_param, &err); + final_suite_set = suite_set; + return 0; - /* Free original suite set before using filtered suite set */ - if (init_num_suites > 0) - kfree(suite_set.start); - suite_set = filtered_suite_set; +free_out: + kunit_free_suite_set(suite_set); - if (err) { - pr_err("kunit executor: error filtering suites: %d\n", err); - goto free_out; - } +out: + kunit_handle_shutdown(); + return err; +} + +late_initcall(kunit_init_suites); + +int kunit_run_all_tests(void) +{ + int err = 0; + + if (!kunit_enabled()) { + pr_info("kunit: disabled\n"); + goto out; } + if (!final_suite_set.start) + goto out; + if (!action_param) - kunit_exec_run_tests(&suite_set, true); + kunit_exec_run_tests(&final_suite_set, true); else if (strcmp(action_param, "list") == 0) - kunit_exec_list_tests(&suite_set, false); + kunit_exec_list_tests(&final_suite_set, false); else if (strcmp(action_param, "list_attr") == 0) - kunit_exec_list_tests(&suite_set, true); + kunit_exec_list_tests(&final_suite_set, true); else pr_err("kunit executor: unknown action '%s'\n", action_param); -free_out: - if (filter_glob_param || filter_param) - kunit_free_suite_set(suite_set); - else if (init_num_suites > 0) - /* Don't use kunit_free_suite_set because suites aren't individually allocated */ - kfree(suite_set.start); + kunit_free_suite_set(final_suite_set); + final_suite_set.start = NULL; + final_suite_set.end = NULL; out: kunit_handle_shutdown(); diff --git a/lib/kunit/kunit-example-test.c b/lib/kunit/kunit-example-test.c index 798924f7cc86..248949eb3b16 100644 --- a/lib/kunit/kunit-example-test.c +++ b/lib/kunit/kunit-example-test.c @@ -337,7 +337,7 @@ static struct kunit_suite example_test_suite = { */ kunit_test_suites(&example_test_suite); -static int __init init_add(int x, int y) +static int init_add(int x, int y) { return (x + y); } @@ -345,7 +345,7 @@ static int __init init_add(int x, int y) /* * This test should always pass. Can be used to test init suites. */ -static void __init example_init_test(struct kunit *test) +static void example_init_test(struct kunit *test) { KUNIT_EXPECT_EQ(test, init_add(1, 1), 2); } @@ -354,7 +354,7 @@ static void __init example_init_test(struct kunit *test) * The kunit_case struct cannot be marked as __initdata as this will be * used in debugfs to retrieve results after test has run */ -static struct kunit_case __refdata example_init_test_cases[] = { +static struct kunit_case example_init_test_cases[] = { KUNIT_CASE(example_init_test), {} }; diff --git a/lib/kunit_iov_iter.c b/lib/kunit_iov_iter.c index 859b67c4d697..a77991a9bffb 100644 --- a/lib/kunit_iov_iter.c +++ b/lib/kunit_iov_iter.c @@ -44,9 +44,8 @@ static void iov_kunit_unmap(void *data) vunmap(data); } -static void *__init iov_kunit_create_buffer(struct kunit *test, - struct page ***ppages, - size_t npages) +static void *iov_kunit_create_buffer(struct kunit *test, struct page ***ppages, + size_t npages) { struct page **pages; unsigned long got; @@ -69,11 +68,10 @@ static void *__init iov_kunit_create_buffer(struct kunit *test, return buffer; } -static void __init iov_kunit_load_kvec(struct kunit *test, - struct iov_iter *iter, int dir, - struct kvec *kvec, unsigned int kvmax, - void *buffer, size_t bufsize, - const struct kvec_test_range *pr) +static void iov_kunit_load_kvec(struct kunit *test, struct iov_iter *iter, + int dir, struct kvec *kvec, unsigned int kvmax, + void *buffer, size_t bufsize, + const struct kvec_test_range *pr) { size_t size = 0; int i; @@ -95,7 +93,7 @@ static void __init iov_kunit_load_kvec(struct kunit *test, /* * Test copying to a ITER_KVEC-type iterator. */ -static void __init iov_kunit_copy_to_kvec(struct kunit *test) +static void iov_kunit_copy_to_kvec(struct kunit *test) { const struct kvec_test_range *pr; struct iov_iter iter; @@ -145,7 +143,7 @@ static void __init iov_kunit_copy_to_kvec(struct kunit *test) /* * Test copying from a ITER_KVEC-type iterator. */ -static void __init iov_kunit_copy_from_kvec(struct kunit *test) +static void iov_kunit_copy_from_kvec(struct kunit *test) { const struct kvec_test_range *pr; struct iov_iter iter; @@ -213,12 +211,11 @@ static const struct bvec_test_range bvec_test_ranges[] = { { -1, -1, -1 } }; -static void __init iov_kunit_load_bvec(struct kunit *test, - struct iov_iter *iter, int dir, - struct bio_vec *bvec, unsigned int bvmax, - struct page **pages, size_t npages, - size_t bufsize, - const struct bvec_test_range *pr) +static void iov_kunit_load_bvec(struct kunit *test, struct iov_iter *iter, + int dir, struct bio_vec *bvec, + unsigned int bvmax, struct page **pages, + size_t npages, size_t bufsize, + const struct bvec_test_range *pr) { struct page *can_merge = NULL, *page; size_t size = 0; @@ -254,7 +251,7 @@ static void __init iov_kunit_load_bvec(struct kunit *test, /* * Test copying to a ITER_BVEC-type iterator. */ -static void __init iov_kunit_copy_to_bvec(struct kunit *test) +static void iov_kunit_copy_to_bvec(struct kunit *test) { const struct bvec_test_range *pr; struct iov_iter iter; @@ -308,7 +305,7 @@ static void __init iov_kunit_copy_to_bvec(struct kunit *test) /* * Test copying from a ITER_BVEC-type iterator. */ -static void __init iov_kunit_copy_from_bvec(struct kunit *test) +static void iov_kunit_copy_from_bvec(struct kunit *test) { const struct bvec_test_range *pr; struct iov_iter iter; @@ -370,10 +367,9 @@ static void iov_kunit_destroy_xarray(void *data) kfree(xarray); } -static void __init iov_kunit_load_xarray(struct kunit *test, - struct iov_iter *iter, int dir, - struct xarray *xarray, - struct page **pages, size_t npages) +static void iov_kunit_load_xarray(struct kunit *test, struct iov_iter *iter, + int dir, struct xarray *xarray, + struct page **pages, size_t npages) { size_t size = 0; int i; @@ -401,7 +397,7 @@ static struct xarray *iov_kunit_create_xarray(struct kunit *test) /* * Test copying to a ITER_XARRAY-type iterator. */ -static void __init iov_kunit_copy_to_xarray(struct kunit *test) +static void iov_kunit_copy_to_xarray(struct kunit *test) { const struct kvec_test_range *pr; struct iov_iter iter; @@ -459,7 +455,7 @@ static void __init iov_kunit_copy_to_xarray(struct kunit *test) /* * Test copying from a ITER_XARRAY-type iterator. */ -static void __init iov_kunit_copy_from_xarray(struct kunit *test) +static void iov_kunit_copy_from_xarray(struct kunit *test) { const struct kvec_test_range *pr; struct iov_iter iter; @@ -522,7 +518,7 @@ static void __init iov_kunit_copy_from_xarray(struct kunit *test) /* * Test the extraction of ITER_KVEC-type iterators. */ -static void __init iov_kunit_extract_pages_kvec(struct kunit *test) +static void iov_kunit_extract_pages_kvec(struct kunit *test) { const struct kvec_test_range *pr; struct iov_iter iter; @@ -602,7 +598,7 @@ static void __init iov_kunit_extract_pages_kvec(struct kunit *test) /* * Test the extraction of ITER_BVEC-type iterators. */ -static void __init iov_kunit_extract_pages_bvec(struct kunit *test) +static void iov_kunit_extract_pages_bvec(struct kunit *test) { const struct bvec_test_range *pr; struct iov_iter iter; @@ -680,7 +676,7 @@ static void __init iov_kunit_extract_pages_bvec(struct kunit *test) /* * Test the extraction of ITER_XARRAY-type iterators. */ -static void __init iov_kunit_extract_pages_xarray(struct kunit *test) +static void iov_kunit_extract_pages_xarray(struct kunit *test) { const struct kvec_test_range *pr; struct iov_iter iter; @@ -756,7 +752,7 @@ static void __init iov_kunit_extract_pages_xarray(struct kunit *test) KUNIT_SUCCEED(); } -static struct kunit_case __refdata iov_kunit_cases[] = { +static struct kunit_case iov_kunit_cases[] = { KUNIT_CASE(iov_kunit_copy_to_kvec), KUNIT_CASE(iov_kunit_copy_from_kvec), KUNIT_CASE(iov_kunit_copy_to_bvec), diff --git a/tools/testing/kunit/kunit_kernel.py b/tools/testing/kunit/kunit_kernel.py index 0b6488efed47..e1980ea58118 100644 --- a/tools/testing/kunit/kunit_kernel.py +++ b/tools/testing/kunit/kunit_kernel.py @@ -104,12 +104,13 @@ class LinuxSourceTreeOperationsQemu(LinuxSourceTreeOperations): self._kconfig = qemu_arch_params.kconfig self._qemu_arch = qemu_arch_params.qemu_arch self._kernel_path = qemu_arch_params.kernel_path - self._kernel_command_line = qemu_arch_params.kernel_command_line + ' kunit_shutdown=reboot' + self._kernel_command_line = qemu_arch_params.kernel_command_line + ' kunit_shutdown=reboot rootfstype=tmpfs' self._extra_qemu_params = qemu_arch_params.extra_qemu_params self._serial = qemu_arch_params.serial def make_arch_config(self, base_kunitconfig: kunit_config.Kconfig) -> kunit_config.Kconfig: kconfig = kunit_config.parse_from_string(self._kconfig) + kconfig.add_entry('TMPFS', 'y') kconfig.merge_in_entries(base_kunitconfig) return kconfig @@ -139,13 +140,14 @@ class LinuxSourceTreeOperationsUml(LinuxSourceTreeOperations): def make_arch_config(self, base_kunitconfig: kunit_config.Kconfig) -> kunit_config.Kconfig: kconfig = kunit_config.parse_file(UML_KCONFIG_PATH) + kconfig.add_entry('TMPFS', 'y') kconfig.merge_in_entries(base_kunitconfig) return kconfig def start(self, params: List[str], build_dir: str) -> subprocess.Popen: """Runs the Linux UML binary. Must be named 'linux'.""" linux_bin = os.path.join(build_dir, 'linux') - params.extend(['mem=1G', 'console=tty', 'kunit_shutdown=halt']) + params.extend(['mem=1G', 'console=tty', 'kunit_shutdown=halt', 'rootfstype=tmpfs']) return subprocess.Popen([linux_bin] + params, stdin=subprocess.PIPE, stdout=subprocess.PIPE, From patchwork Thu Feb 29 17:04:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= X-Patchwork-Id: 13577458 Received: from smtp-1908.mail.infomaniak.ch (smtp-1908.mail.infomaniak.ch [185.125.25.8]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 210184AECF for ; Thu, 29 Feb 2024 17:04:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.125.25.8 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709226279; cv=none; b=l72V0gA4SLk27l5H5+yM8GQGXVGSFHxWeWHYUcmQOGzPE6LIDNjPPa1vbOQItYTGkYvs2Dyi6j1iZbkzf6k/n2Ld6hUhSgyPPYLWJ+Ytc/5SV+NjcQemHgwtySu3E9Lo2YnerdBG9w0zqRJkLOs5idN42sBvEOxiF+eGA8jrzeM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709226279; c=relaxed/simple; bh=iEMsEf9vHd9/SI1OU/FMhsYF3Xf0RZ6zSUY0txBsePY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Xf1NvZ0VWk+jKUdReRatL9XYgndnKzdUJwMe5aHvYimN+Y1ZZc5hxXM6BL7P5XPc1Lg/4Ng+FuHDfA423XjXRG7vkE+cHn8DVfnNqTK1LJukq6VwJpCES+m0eOFjue/Timi6VYHMwAfYE3KCsNBbFL7VvmnJofvgXqJ1XdI4wV0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=digikod.net; spf=pass smtp.mailfrom=digikod.net; dkim=pass (1024-bit key) header.d=digikod.net header.i=@digikod.net header.b=mt5sEYwZ; arc=none smtp.client-ip=185.125.25.8 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=digikod.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=digikod.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=digikod.net header.i=@digikod.net header.b="mt5sEYwZ" Received: from smtp-3-0000.mail.infomaniak.ch (unknown [10.4.36.107]) by smtp-3-3000.mail.infomaniak.ch (Postfix) with ESMTPS id 4TlyHs3xr2zMrktf; Thu, 29 Feb 2024 18:04:25 +0100 (CET) Received: from unknown by smtp-3-0000.mail.infomaniak.ch (Postfix) with ESMTPA id 4TlyHr5l81zsG; Thu, 29 Feb 2024 18:04:24 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=digikod.net; s=20191114; t=1709226265; bh=iEMsEf9vHd9/SI1OU/FMhsYF3Xf0RZ6zSUY0txBsePY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mt5sEYwZdJqMXsg2RNP3sZk7FXe2d42pQAwMlKqEqVeZoUnZxWKILpymJr3/osTy1 HATdiX6VsrwoP0gD2blvTb19qjeTYzsRp4SafqrsoXPddY8xyBu1Qc8e4S1DueQbzl Gv250bTvI44E66febWNikJHzk267euM4+x5fW+J8= From: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= To: Brendan Higgins , David Gow , Kees Cook , Rae Moar , Shuah Khan Cc: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= , Alan Maguire , Borislav Petkov , Dave Hansen , "H . Peter Anvin" , Ingo Molnar , James Morris , Luis Chamberlain , "Madhavan T . Venkataraman" , Marco Pagani , Paolo Bonzini , Sean Christopherson , Stephen Boyd , Thara Gopinath , Thomas Gleixner , Vitaly Kuznetsov , Wanpeng Li , Zahra Tarkhani , kvm@vger.kernel.org, linux-hardening@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, linux-um@lists.infradead.org, x86@kernel.org Subject: [PATCH v1 2/8] kunit: Handle thread creation error Date: Thu, 29 Feb 2024 18:04:03 +0100 Message-ID: <20240229170409.365386-3-mic@digikod.net> In-Reply-To: <20240229170409.365386-1-mic@digikod.net> References: <20240229170409.365386-1-mic@digikod.net> Precedence: bulk X-Mailing-List: linux-hardening@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Infomaniak-Routing: alpha 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 Cc: David Gow Cc: Rae Moar Cc: Shuah Khan Signed-off-by: Mickaël Salaün Reviewed-by: Kees Cook --- 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; } From patchwork Thu Feb 29 17:04:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= X-Patchwork-Id: 13577455 Received: from smtp-42ae.mail.infomaniak.ch (smtp-42ae.mail.infomaniak.ch [84.16.66.174]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6F3B84AED6 for ; Thu, 29 Feb 2024 17:04:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=84.16.66.174 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709226277; cv=none; b=okBYPt7/Wj/8aQFw7MkkqjREZ/vWLh4nkyvRdkYO1S3maZBo4rFldrvSFWUuPdKNPliE6kLZ7BFLcb4BDyl3hHSetGH8xOL1s7hI7UqxILIeRIBtowNCwTPlsOMOUyDHAV9lEQSlDOE6lpaGqyS8yzcXikVJUGpHIZ4FptLZ2AA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709226277; c=relaxed/simple; bh=f3wQ1gxeTPJnB2/Gx7Deo/AawwvRjdcM6xP+hwNtgJY=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=KEmfoe8pcIRkOrR96prnb21IxZTZ5N4luf/5JRID1l6Uvn8pvTethbPHfvTba3IPzN+BsyGBCg//bb8WfRB6zyssdenFP8spzyHPVqNfQvm4KAb8yzSdICHxvCbSrBJswtquNItjklDW8KRLr5GEBSbsHo+zlkkdLaocPHiIMc8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=digikod.net; spf=pass smtp.mailfrom=digikod.net; dkim=pass (1024-bit key) header.d=digikod.net header.i=@digikod.net header.b=gcmoNxGK; arc=none smtp.client-ip=84.16.66.174 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=digikod.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=digikod.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=digikod.net header.i=@digikod.net header.b="gcmoNxGK" Received: from smtp-3-0000.mail.infomaniak.ch (unknown [10.4.36.107]) by smtp-3-3000.mail.infomaniak.ch (Postfix) with ESMTPS id 4TlyHt43J2zMrktk; Thu, 29 Feb 2024 18:04:26 +0100 (CET) Received: from unknown by smtp-3-0000.mail.infomaniak.ch (Postfix) with ESMTPA id 4TlyHt04GMz3g; Thu, 29 Feb 2024 18:04:26 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=digikod.net; s=20191114; t=1709226266; bh=f3wQ1gxeTPJnB2/Gx7Deo/AawwvRjdcM6xP+hwNtgJY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=gcmoNxGKgHYnKVXBDTBQhQzczqpk0AxQqq9JNXYdDODHvh/MAoOXfB/kwfdeEagYp NERBG2Kr74hChpupRTAofgZCk4ummr2hEYGU9T9zi+Tiqlcq/wnfCSFRB+ktAVcOJM XfkR6BWeRDyyrWQGtYg1MRUyDHGWxF7r/xVDhEOA= From: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= To: Brendan Higgins , David Gow , Kees Cook , Rae Moar , Shuah Khan Cc: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= , Alan Maguire , Borislav Petkov , Dave Hansen , "H . Peter Anvin" , Ingo Molnar , James Morris , Luis Chamberlain , "Madhavan T . Venkataraman" , Marco Pagani , Paolo Bonzini , Sean Christopherson , Stephen Boyd , Thara Gopinath , Thomas Gleixner , Vitaly Kuznetsov , Wanpeng Li , Zahra Tarkhani , kvm@vger.kernel.org, linux-hardening@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, linux-um@lists.infradead.org, x86@kernel.org Subject: [PATCH v1 3/8] kunit: Fix kthread reference Date: Thu, 29 Feb 2024 18:04:04 +0100 Message-ID: <20240229170409.365386-4-mic@digikod.net> In-Reply-To: <20240229170409.365386-1-mic@digikod.net> References: <20240229170409.365386-1-mic@digikod.net> Precedence: bulk X-Mailing-List: linux-hardening@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Infomaniak-Routing: alpha 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 Cc: David Gow Cc: Rae Moar Cc: Shuah Khan Signed-off-by: Mickaël Salaün Reviewed-by: Kees Cook --- 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 #include #include +#include #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) From patchwork Thu Feb 29 17:04:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= X-Patchwork-Id: 13577457 Received: from smtp-bc0c.mail.infomaniak.ch (smtp-bc0c.mail.infomaniak.ch [45.157.188.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 91FB94AEEC for ; Thu, 29 Feb 2024 17:04:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.157.188.12 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709226277; cv=none; b=AEnBr6f3Q6cfqS7TlJvYFFJKKEhaVkskHCYTjvarBVxbdvJGIdt1hjVZS72voth/GZNSCMyx1NeTc9pgphJZ7ZAcN8dngavY1f81VRFv8TW5t4iz1Q9u/M0lz8u+QQYRq+LEn1y5Ik6TxhG7qAmdqbPdZPV4iiTfNC7Vc4+vU1E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709226277; c=relaxed/simple; bh=uBMChHU5UNMlEl3ATgwx20Pp9VOumM9CW4wvZ2gv728=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=PJinR9vgKKU7mAIGI6Vl0PtUcOK+n2zeaswSHgmOt//fxoMApYRWIBsiOSKpmq3+sqrZGDQV+4WbWGJPQ6EHiKHBG1+LrG1mcLWWqqaoFFhJOPkeTVp1hidsrw5OVi+g0grlKeex64xYR8hJgP7IShlpO6ode4U4VvgrmAaq6fA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=digikod.net; spf=pass smtp.mailfrom=digikod.net; dkim=pass (1024-bit key) header.d=digikod.net header.i=@digikod.net header.b=g3VQrtX/; arc=none smtp.client-ip=45.157.188.12 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=digikod.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=digikod.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=digikod.net header.i=@digikod.net header.b="g3VQrtX/" Received: from smtp-3-0001.mail.infomaniak.ch (unknown [10.4.36.108]) by smtp-3-3000.mail.infomaniak.ch (Postfix) with ESMTPS id 4TlyHv6JJjzMrkvR; Thu, 29 Feb 2024 18:04:27 +0100 (CET) Received: from unknown by smtp-3-0001.mail.infomaniak.ch (Postfix) with ESMTPA id 4TlyHv0Y1GzMppV9; Thu, 29 Feb 2024 18:04:27 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=digikod.net; s=20191114; t=1709226267; bh=uBMChHU5UNMlEl3ATgwx20Pp9VOumM9CW4wvZ2gv728=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=g3VQrtX/j4mrYOK5lCD4XPwom/SI0/y/0R4myV2rOLoAWJbQXs3vRNiqY7hBGvPKt IWhFH8Ae2AB6sbRZrZYR+D0SJT6lcgzTL2uwOpY7ATOhYsFr6lnwl26n6gEktkAfAl F696GqV8G1WnaDB4mg5K41u90uy9ksSd19IE4k0Q= From: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= To: Brendan Higgins , David Gow , Kees Cook , Rae Moar , Shuah Khan Cc: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= , Alan Maguire , Borislav Petkov , Dave Hansen , "H . Peter Anvin" , Ingo Molnar , James Morris , Luis Chamberlain , "Madhavan T . Venkataraman" , Marco Pagani , Paolo Bonzini , Sean Christopherson , Stephen Boyd , Thara Gopinath , Thomas Gleixner , Vitaly Kuznetsov , Wanpeng Li , Zahra Tarkhani , kvm@vger.kernel.org, linux-hardening@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, linux-um@lists.infradead.org, x86@kernel.org Subject: [PATCH v1 4/8] kunit: Fix timeout message Date: Thu, 29 Feb 2024 18:04:05 +0100 Message-ID: <20240229170409.365386-5-mic@digikod.net> In-Reply-To: <20240229170409.365386-1-mic@digikod.net> References: <20240229170409.365386-1-mic@digikod.net> Precedence: bulk X-Mailing-List: linux-hardening@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Infomaniak-Routing: alpha The exit code is always checked, so let's properly handle the -ETIMEDOUT error code. Cc: Brendan Higgins Cc: David Gow Cc: Rae Moar Cc: Shuah Khan Signed-off-by: Mickaël Salaün Reviewed-by: Kees Cook --- 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); From patchwork Thu Feb 29 17:04:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= X-Patchwork-Id: 13577459 Received: from smtp-8fac.mail.infomaniak.ch (smtp-8fac.mail.infomaniak.ch [83.166.143.172]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 03C6D6CBFD for ; Thu, 29 Feb 2024 17:04:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=83.166.143.172 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709226279; cv=none; b=bJDP0Y82k/Lw/bYoez3xmRIQPmUDUZVVJmEA4yJuAYykwgU+A80nxCG+NYYmzl+tjOG2A60RLywlrEdTiVWHrWOQHZAEUMUUPHxl3NqZdnsKQmreTHYKqFHRme/uWqeYtgAgXDdifRwGisndmbXQSm5vP2VsWgcNielhUkRQ6nE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709226279; c=relaxed/simple; bh=Y3qACsJqLhysHNo72GvJJ9/ipSm5FWvUJD/HQrH2Nac=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=GdPDc7wjIfATecTxfpiyNtfZHdWr12I52jONM3xci++3z1GhtQJS5SIrS5aGMsjpY3kK74UKsGbAIdNEF1K3KQOKBglwfb8pwY3SbeGDftfFMIiFWFJU+64vbstGIFRsj5WAT6lFbQZLbRnntBBlPKlgIfTxDBdGTUMQVamoGVY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=digikod.net; spf=pass smtp.mailfrom=digikod.net; dkim=pass (1024-bit key) header.d=digikod.net header.i=@digikod.net header.b=I5diwHoF; arc=none smtp.client-ip=83.166.143.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=digikod.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=digikod.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=digikod.net header.i=@digikod.net header.b="I5diwHoF" Received: from smtp-3-0001.mail.infomaniak.ch (unknown [10.4.36.108]) by smtp-3-3000.mail.infomaniak.ch (Postfix) with ESMTPS id 4TlyHx0XD1zMrkvK; Thu, 29 Feb 2024 18:04:29 +0100 (CET) Received: from unknown by smtp-3-0001.mail.infomaniak.ch (Postfix) with ESMTPA id 4TlyHw2tVRzMpnPj; Thu, 29 Feb 2024 18:04:28 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=digikod.net; s=20191114; t=1709226268; bh=Y3qACsJqLhysHNo72GvJJ9/ipSm5FWvUJD/HQrH2Nac=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=I5diwHoFMOe7e+VCX9Kpc4Al+7OLJ05syQxgO2eEWWeYFE3i8xxvjPFVksjKES4Ar RnEM/+1JzGqSBFIyaugTPitDZeybVukdsrcbU1APqTnUmUjFjQPZxwWwCDq4fU/Q2L IWKprJuZaq2OiK0trID+Wsx8+VnPmd7Z4Vh5Y+G0= From: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= To: Brendan Higgins , David Gow , Kees Cook , Rae Moar , Shuah Khan Cc: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= , Alan Maguire , Borislav Petkov , Dave Hansen , "H . Peter Anvin" , Ingo Molnar , James Morris , Luis Chamberlain , "Madhavan T . Venkataraman" , Marco Pagani , Paolo Bonzini , Sean Christopherson , Stephen Boyd , Thara Gopinath , Thomas Gleixner , Vitaly Kuznetsov , Wanpeng Li , Zahra Tarkhani , kvm@vger.kernel.org, linux-hardening@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, linux-um@lists.infradead.org, x86@kernel.org Subject: [PATCH v1 5/8] kunit: Handle test faults Date: Thu, 29 Feb 2024 18:04:06 +0100 Message-ID: <20240229170409.365386-6-mic@digikod.net> In-Reply-To: <20240229170409.365386-1-mic@digikod.net> References: <20240229170409.365386-1-mic@digikod.net> Precedence: bulk X-Mailing-List: linux-hardening@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Infomaniak-Routing: alpha 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 -EFAULT 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 Cc: David Gow Cc: Rae Moar Cc: Shuah Khan Signed-off-by: Mickaël Salaün Reviewed-by: Kees Cook --- include/kunit/try-catch.h | 3 --- lib/kunit/try-catch.c | 14 +++++++------- 2 files changed, 7 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..c6ee4db0b3bd 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,7 @@ 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, + time_remaining = wait_for_completion_timeout(task_struct->vfork_done, kunit_test_timeout()); if (time_remaining == 0) { try_catch->try_result = -ETIMEDOUT; @@ -92,7 +92,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) From patchwork Thu Feb 29 17:04:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= X-Patchwork-Id: 13577460 Received: from smtp-42a8.mail.infomaniak.ch (smtp-42a8.mail.infomaniak.ch [84.16.66.168]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A883E6CC1E for ; Thu, 29 Feb 2024 17:04:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=84.16.66.168 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709226280; cv=none; b=Un+ittWPU/rkU3d4jIhD6Fak68bnieoc8ryf2SHmxPfyDDs3EBCEL4jBNueuesmAsgyGguuTm08YHuTOyz1B8r5CQZPwCAREzmhfhdGDAyNjT/MG36Zq7yWTcmIq2TRGMA9fHjgiwzSbSc4LDeyh3lnED8Z54n0ItwyUE5sIu04= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709226280; c=relaxed/simple; bh=njKd78Dlxcb8LNFqK0Y6SC5BCIGDfZPNfNKkSCugFkg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ICffkD2Z2y4FHSZJz+vY/i51kIl0iuOWcYh+WHGsXOZDdNrX+dg5XcECYnc533+/y68sKp3VbonzURpSzkiyu1p+N24fvU8Qg7dCgM8soUfopFCn3bchSFTBvsxdW2XekGkFnsD+3trNOEELmuQOjqaEnYtNjsGrSo3injJP4QM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=digikod.net; spf=pass smtp.mailfrom=digikod.net; dkim=pass (1024-bit key) header.d=digikod.net header.i=@digikod.net header.b=tSl8YApK; arc=none smtp.client-ip=84.16.66.168 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=digikod.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=digikod.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=digikod.net header.i=@digikod.net header.b="tSl8YApK" Received: from smtp-3-0001.mail.infomaniak.ch (unknown [10.4.36.108]) by smtp-3-3000.mail.infomaniak.ch (Postfix) with ESMTPS id 4TlyHy3694zMrkv9; Thu, 29 Feb 2024 18:04:30 +0100 (CET) Received: from unknown by smtp-3-0001.mail.infomaniak.ch (Postfix) with ESMTPA id 4TlyHx3kNwzMppVF; Thu, 29 Feb 2024 18:04:29 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=digikod.net; s=20191114; t=1709226270; bh=njKd78Dlxcb8LNFqK0Y6SC5BCIGDfZPNfNKkSCugFkg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tSl8YApK6lTMIm1P9is6nUyb70iS56zUvtW6vvPpqkeaUL8jxgCoM51JKQUjF9ssj cY8uUxa/dhGRdbk00nKuP/PM9L467aNrqqbYwMVsbB96Q4+RBvLJokVbpLp5r41i8A FSsOtrx+hLcfiz7OU/wAdcXDQcIhO/+DrngS1G5A= From: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= To: Brendan Higgins , David Gow , Kees Cook , Rae Moar , Shuah Khan Cc: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= , Alan Maguire , Borislav Petkov , Dave Hansen , "H . Peter Anvin" , Ingo Molnar , James Morris , Luis Chamberlain , "Madhavan T . Venkataraman" , Marco Pagani , Paolo Bonzini , Sean Christopherson , Stephen Boyd , Thara Gopinath , Thomas Gleixner , Vitaly Kuznetsov , Wanpeng Li , Zahra Tarkhani , kvm@vger.kernel.org, linux-hardening@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, linux-um@lists.infradead.org, x86@kernel.org Subject: [PATCH v1 6/8] kunit: Fix KUNIT_SUCCESS() calls in iov_iter tests Date: Thu, 29 Feb 2024 18:04:07 +0100 Message-ID: <20240229170409.365386-7-mic@digikod.net> In-Reply-To: <20240229170409.365386-1-mic@digikod.net> References: <20240229170409.365386-1-mic@digikod.net> Precedence: bulk X-Mailing-List: linux-hardening@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Infomaniak-Routing: alpha 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 Cc: David Gow Cc: Rae Moar Cc: Shuah Khan Signed-off-by: Mickaël Salaün Reviewed-by: Kees Cook --- 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 a77991a9bffb..b586aa19e45d 100644 --- a/lib/kunit_iov_iter.c +++ b/lib/kunit_iov_iter.c @@ -137,7 +137,7 @@ static void iov_kunit_copy_to_kvec(struct kunit *test) return; } - KUNIT_SUCCEED(); + KUNIT_SUCCEED(test); } /* @@ -192,7 +192,7 @@ static void iov_kunit_copy_from_kvec(struct kunit *test) return; } - KUNIT_SUCCEED(); + KUNIT_SUCCEED(test); } struct bvec_test_range { @@ -299,7 +299,7 @@ static void iov_kunit_copy_to_bvec(struct kunit *test) return; } - KUNIT_SUCCEED(); + KUNIT_SUCCEED(test); } /* @@ -356,7 +356,7 @@ static void iov_kunit_copy_from_bvec(struct kunit *test) return; } - KUNIT_SUCCEED(); + KUNIT_SUCCEED(test); } static void iov_kunit_destroy_xarray(void *data) @@ -449,7 +449,7 @@ static void iov_kunit_copy_to_xarray(struct kunit *test) return; } - KUNIT_SUCCEED(); + KUNIT_SUCCEED(test); } /* @@ -512,7 +512,7 @@ static void iov_kunit_copy_from_xarray(struct kunit *test) return; } - KUNIT_SUCCEED(); + KUNIT_SUCCEED(test); } /* @@ -592,7 +592,7 @@ static void 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); } /* @@ -670,7 +670,7 @@ static void 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); } /* @@ -749,7 +749,7 @@ static void iov_kunit_extract_pages_xarray(struct kunit *test) } stop: - KUNIT_SUCCEED(); + KUNIT_SUCCEED(test); } static struct kunit_case iov_kunit_cases[] = { From patchwork Thu Feb 29 17:04:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= X-Patchwork-Id: 13577461 Received: from smtp-bc0d.mail.infomaniak.ch (smtp-bc0d.mail.infomaniak.ch [45.157.188.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 84B7475805 for ; Thu, 29 Feb 2024 17:04:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.157.188.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709226281; cv=none; b=u4fjuGYTkk68+7nLJFocFoXBCeLsSZWeoSKaYtH2z5nHgg+N+qfo8zYzvomC0aGQrQhKt8UuZD4QTyrPpkIMH1aY1LzXSd/8KzlQ7wQR22uAZABhsGTGdj/7tfkPwMzQV05JJsDRM67qOaIdJVdNorakyKWX7lAfE5ne6Fy0tFA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709226281; c=relaxed/simple; bh=NVotNwUXraMtMy/B110wUmXv9rleT0r5CtHb/0J/Dyw=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=qQuu+EfGpDjekWiVbyblfXK+YbsJncQZxSrae1vWETMCF+/UDx7WFHQmb76vyzUL+dMeNeeEDqIUfQVC7VyU2zW1QpdVIEcpRF0R2P+qdkhH5VKmJRF4WpANcpxbXa/5tmWUomdHYxxgssSmQECJtCr/BCVHyQHLr8Rrd7CflhA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=digikod.net; spf=pass smtp.mailfrom=digikod.net; dkim=pass (1024-bit key) header.d=digikod.net header.i=@digikod.net header.b=v0ThMtvM; arc=none smtp.client-ip=45.157.188.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=digikod.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=digikod.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=digikod.net header.i=@digikod.net header.b="v0ThMtvM" Received: from smtp-3-0001.mail.infomaniak.ch (smtp-3-0001.mail.infomaniak.ch [10.4.36.108]) by smtp-4-3000.mail.infomaniak.ch (Postfix) with ESMTPS id 4TlyHz56S6z4gr; Thu, 29 Feb 2024 18:04:31 +0100 (CET) Received: from unknown by smtp-3-0001.mail.infomaniak.ch (Postfix) with ESMTPA id 4TlyHy6lfzzMpnPg; Thu, 29 Feb 2024 18:04:30 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=digikod.net; s=20191114; t=1709226271; bh=NVotNwUXraMtMy/B110wUmXv9rleT0r5CtHb/0J/Dyw=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=v0ThMtvMj3vwpEvud2gvTCdQ6gPp6BUqR0ZH1b2ga4w+aG1idRjI+PdHZvDQlNReK WSAYLTjdGaQDAiMpkzddcFFklAPbvKVr5xyFUPQTemYKqVNu8cofKAuqTxW37iWLme wzfUX2mHyq7IPKwAvyHc6yD8MU/k+i5XrxB4/pKE= From: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= To: Brendan Higgins , David Gow , Kees Cook , Rae Moar , Shuah Khan Cc: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= , Alan Maguire , Borislav Petkov , Dave Hansen , "H . Peter Anvin" , Ingo Molnar , James Morris , Luis Chamberlain , "Madhavan T . Venkataraman" , Marco Pagani , Paolo Bonzini , Sean Christopherson , Stephen Boyd , Thara Gopinath , Thomas Gleixner , Vitaly Kuznetsov , Wanpeng Li , Zahra Tarkhani , kvm@vger.kernel.org, linux-hardening@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, linux-um@lists.infradead.org, x86@kernel.org Subject: [PATCH v1 7/8] kunit: Print last test location on fault Date: Thu, 29 Feb 2024 18:04:08 +0100 Message-ID: <20240229170409.365386-8-mic@digikod.net> In-Reply-To: <20240229170409.365386-1-mic@digikod.net> References: <20240229170409.365386-1-mic@digikod.net> Precedence: bulk X-Mailing-List: linux-hardening@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Infomaniak-Routing: alpha This helps identify the location of test faults. Cc: Brendan Higgins Cc: David Gow Cc: Rae Moar Cc: Shuah Khan Signed-off-by: Mickaël Salaün Reviewed-by: Kees Cook --- 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 c6ee4db0b3bd..2ec21c6918f3 100644 --- a/lib/kunit/try-catch.c +++ b/lib/kunit/try-catch.c @@ -91,9 +91,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); From patchwork Thu Feb 29 17:04:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= X-Patchwork-Id: 13577462 Received: from smtp-8fab.mail.infomaniak.ch (smtp-8fab.mail.infomaniak.ch [83.166.143.171]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AA3BB7A13A for ; Thu, 29 Feb 2024 17:04:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=83.166.143.171 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709226283; cv=none; b=sW0T2+U1rhqFSihg1j/0CyUKmNTtW/nE+D2Jgzf1WzeJ3OE8X1rCVq9L70lg0/qu0i/eHYz6OQzC3GczJhjlKCZDGuMWa1emqTyjZACnCHIkMDNtiXNBChFryVRmiDi6HT03/4tfEu0QbLOBOsdo2mE2jDcnCoRP33mbdujQIsU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1709226283; c=relaxed/simple; bh=jgxgVIds0Uq+q7sp2eMMdlRM5SUWajSTadOwGNRm2Fs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=VgyeuUZ/+ldQwycJ88VIROtWT14dlgkdwH1TXwDCbpQ0cXcIp+Y4Vt6xLHzL/KsmGUVGEzVjNlPL0vynKjQ0tVFMHkyRJBJKPxbCCL+D3g4fbzGAcRXcONbZVqw5tMNZtTOTeER8+OmYnrf4el4HcMsvtD8HvHl895brRI3snes= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=digikod.net; spf=pass smtp.mailfrom=digikod.net; dkim=pass (1024-bit key) header.d=digikod.net header.i=@digikod.net header.b=O7SkJiHr; arc=none smtp.client-ip=83.166.143.171 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=digikod.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=digikod.net Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=digikod.net header.i=@digikod.net header.b="O7SkJiHr" Received: from smtp-3-0000.mail.infomaniak.ch (smtp-3-0000.mail.infomaniak.ch [10.4.36.107]) by smtp-4-3000.mail.infomaniak.ch (Postfix) with ESMTPS id 4TlyJ06NtNz23G; Thu, 29 Feb 2024 18:04:32 +0100 (CET) Received: from unknown by smtp-3-0000.mail.infomaniak.ch (Postfix) with ESMTPA id 4TlyJ01KS6z3c; Thu, 29 Feb 2024 18:04:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=digikod.net; s=20191114; t=1709226272; bh=jgxgVIds0Uq+q7sp2eMMdlRM5SUWajSTadOwGNRm2Fs=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=O7SkJiHrACJveUBYih6KHS2MoK6Y4pu39o0bmrh+/H6EdBfY1u3VZX8uGsKFJXi+a WByMKyxBUC+h89F9ItJ41Svn8x0gBISiaYBOEAxH4PZonYP3aTFWiPtMTboZgZYUP1 9KoOsvsJogUIH9wR1oxyIDnWxnLfeIr+w9ncsLKQ= From: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= To: Brendan Higgins , David Gow , Kees Cook , Rae Moar , Shuah Khan Cc: =?utf-8?q?Micka=C3=ABl_Sala=C3=BCn?= , Alan Maguire , Borislav Petkov , Dave Hansen , "H . Peter Anvin" , Ingo Molnar , James Morris , Luis Chamberlain , "Madhavan T . Venkataraman" , Marco Pagani , Paolo Bonzini , Sean Christopherson , Stephen Boyd , Thara Gopinath , Thomas Gleixner , Vitaly Kuznetsov , Wanpeng Li , Zahra Tarkhani , kvm@vger.kernel.org, linux-hardening@vger.kernel.org, linux-hyperv@vger.kernel.org, linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, linux-um@lists.infradead.org, x86@kernel.org Subject: [PATCH v1 8/8] kunit: Add tests for faults Date: Thu, 29 Feb 2024 18:04:09 +0100 Message-ID: <20240229170409.365386-9-mic@digikod.net> In-Reply-To: <20240229170409.365386-1-mic@digikod.net> References: <20240229170409.365386-1-mic@digikod.net> Precedence: bulk X-Mailing-List: linux-hardening@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Infomaniak-Routing: alpha 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 Cc: David Gow Cc: Rae Moar Cc: Shuah Khan Signed-off-by: Mickaël Salaün --- 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 #include +#include #include #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");