2024-02-14 11:33:06

by Petr Tesarik

[permalink] [raw]
Subject: [PATCH v1 4/5] sbm: SandBox Mode KUnit test suite

From: Petr Tesarik <[email protected]>

Test that a function called in sandbox mode can use input and output
buffers but blocks attempts to read or write outside the pre-defined
memory areas.

Some tests intentionally access a non-present page, which generates a page
fault in kernel space if SBM implementation cannot recover from failures.
Theoretically, the page fault handler could recover from such page faults,
but the exact details differ across architectures, and there is no
universal method. The most portable approach is to let the page fault
handler treat the fault as unrecoverable and kill the current task. This is
why a child task is used to run these tests. The parent KUnit thread can
check if the child was killed with a signal.

Signed-off-by: Petr Tesarik <[email protected]>
---
kernel/Kconfig.sbm | 12 +
kernel/Makefile | 1 +
kernel/sbm_test.c | 735 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 748 insertions(+)
create mode 100644 kernel/sbm_test.c

diff --git a/kernel/Kconfig.sbm b/kernel/Kconfig.sbm
index 64d683cefd4d..d28a754bc704 100644
--- a/kernel/Kconfig.sbm
+++ b/kernel/Kconfig.sbm
@@ -29,3 +29,15 @@ config SANDBOX_MODE
and leaving the sandbox.

If unsure, say N.
+
+config SBM_KUNIT_TEST
+ tristate "Unit tests for SandBox Mode" if !KUNIT_ALL_TESTS
+ depends on KUNIT && SANDBOX_MODE
+ default KUNIT_ALL_TESTS
+ help
+ Build unit tests for SandBox Mode.
+
+ For more information on KUnit and unit tests in general, please refer
+ to the KUnit documentation in Documentation/dev-tools/kunit/.
+
+ If unsure, say N.
diff --git a/kernel/Makefile b/kernel/Makefile
index ecc4bfd6213f..012df6fd817a 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -116,6 +116,7 @@ obj-$(CONFIG_HAVE_STATIC_CALL_INLINE) += static_call_inline.o
obj-$(CONFIG_CFI_CLANG) += cfi.o
obj-$(CONFIG_NUMA) += numa.o
obj-$(CONFIG_SANDBOX_MODE) += sbm.o
+obj-$(CONFIG_SBM_KUNIT_TEST) += sbm_test.o

obj-$(CONFIG_PERF_EVENTS) += events/

diff --git a/kernel/sbm_test.c b/kernel/sbm_test.c
new file mode 100644
index 000000000000..f3ad24ccf332
--- /dev/null
+++ b/kernel/sbm_test.c
@@ -0,0 +1,735 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023-2024 Huawei Technologies Duesseldorf GmbH
+ */
+
+#include <kunit/test.h>
+
+#include <linux/sbm.h>
+#include <linux/sched.h>
+#include <linux/sched/task.h>
+#include <linux/sched/task_stack.h>
+#include <linux/signal.h>
+
+#define PASS 0x600d600d
+#define FAIL 0xbad00bad
+
+struct data {
+ int value;
+};
+
+struct page_over {
+ union {
+ unsigned char page[PAGE_SIZE];
+ struct data data;
+ };
+ int nextpage;
+};
+
+struct thread_data {
+ const struct data *in;
+ struct data *out;
+};
+
+typedef int (*sbm_threadfn)(struct kunit *test, struct thread_data *data);
+
+struct thread_param {
+ struct kunit *test;
+ sbm_threadfn threadfn;
+ struct thread_data *data;
+ int err;
+};
+
+static void check_safe_sbm(struct kunit *test)
+{
+ if (!IS_ENABLED(CONFIG_HAVE_ARCH_SBM))
+ kunit_skip(test, "requires arch hooks");
+}
+
+/**************************************************************
+ * Helpers to handle Oops in a sandbox mode kernel thread
+ *
+ * The kernel does not offer a general method for recovering
+ * from page faults in kernel mode. To intercept a planned
+ * page fault, let a helper thread oops and die.
+ */
+
+static int call_sbm_threadfn(void *arg)
+{
+ struct thread_param *params = arg;
+
+ params->err = params->threadfn(params->test, params->data);
+ do_exit(0);
+}
+
+static int run_sbm_kthread(struct kunit *test, sbm_threadfn threadfn,
+ struct thread_data *data)
+{
+ struct thread_param params = {
+ .test = test,
+ .threadfn = threadfn,
+ .data = data,
+ };
+ int pid, status;
+
+ /* Do not let the child autoreap. */
+ kernel_sigaction(SIGCHLD, SIG_DFL);
+
+ pid = kernel_thread(call_sbm_threadfn, &params, test->name,
+ CLONE_FS | CLONE_FILES | SIGCHLD);
+ KUNIT_ASSERT_GT(test, pid, 0);
+ KUNIT_ASSERT_EQ(test, kernel_wait(pid, &status), pid);
+
+ /* Ignore SIGCHLD again. */
+ kernel_sigaction(SIGCHLD, SIG_IGN);
+
+ /* Killed by a signal? */
+ if (status & 0x7f)
+ return -EFAULT;
+
+ KUNIT_ASSERT_EQ(test, status, 0);
+ return params.err;
+}
+
+/**************************************************************
+ * Simple write to output buffer.
+ *
+ * Verify that the output buffer is copied back to the caller.
+ */
+
+static SBM_DEFINE_FUNC(write, struct data *, out)
+{
+ out->value = PASS;
+ return 0;
+}
+
+static void sbm_write(struct kunit *test)
+{
+ struct sbm sbm;
+ struct data out;
+ int err;
+
+ out.value = FAIL;
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, write,
+ SBM_COPY_OUT(&sbm, &out, sizeof(out)));
+ sbm_destroy(&sbm);
+
+ KUNIT_EXPECT_EQ(test, err, 0);
+ KUNIT_EXPECT_EQ(test, sbm_error(&sbm), 0);
+ KUNIT_EXPECT_EQ(test, out.value, PASS);
+}
+
+/**************************************************************
+ * Memory write past output buffer within the same page.
+ *
+ * Writes beyond buffer end are ignored.
+ */
+
+static SBM_DEFINE_FUNC(write_past, struct data *, out)
+{
+ out[0].value = PASS;
+ out[1].value = FAIL;
+
+ return 0;
+}
+
+static void sbm_write_past(struct kunit *test)
+{
+ struct sbm sbm;
+ struct data out[2];
+ int err;
+
+ out[0].value = FAIL;
+ out[1].value = PASS;
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, write_past,
+ SBM_COPY_OUT(&sbm, &out[0], sizeof(out[0])));
+ sbm_destroy(&sbm);
+
+ KUNIT_EXPECT_EQ(test, err, 0);
+ KUNIT_EXPECT_EQ(test, sbm_error(&sbm), 0);
+ KUNIT_EXPECT_EQ(test, out[0].value, PASS);
+ KUNIT_EXPECT_EQ(test, out[1].value, PASS);
+}
+
+/**************************************************************
+ * Memory write to next page past output buffer.
+ *
+ * There is a guard page after the output buffer. Writes to
+ * this guard page should generate a page fault.
+ */
+
+static SBM_DEFINE_FUNC(write_past_page, struct data *, out)
+{
+ struct page_over *over = (struct page_over *)out;
+
+ over->nextpage = FAIL;
+ barrier();
+ out[0].value = FAIL;
+ return 0;
+}
+
+static int sbm_write_past_page_threadfn(struct kunit *text,
+ struct thread_data *data)
+{
+ struct sbm sbm;
+ int err;
+
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, write_past_page,
+ SBM_COPY_OUT(&sbm, data->out, sizeof(*data->out)));
+ sbm_destroy(&sbm);
+ return err;
+}
+
+static void sbm_write_past_page(struct kunit *test)
+{
+ struct page_over *over;
+ int err;
+
+ over = kunit_kzalloc(test, sizeof(*over), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, over);
+ over->data.value = PASS;
+ over->nextpage = PASS;
+ if (IS_ENABLED(CONFIG_HAVE_ARCH_SBM)) {
+ struct sbm sbm;
+
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, write_past_page,
+ SBM_COPY_OUT(&sbm, &over->data,
+ sizeof(over->data)));
+ KUNIT_EXPECT_EQ(test, sbm_error(&sbm), -EFAULT);
+ sbm_destroy(&sbm);
+ } else {
+ struct thread_data data;
+
+ data.out = &over->data;
+ err = run_sbm_kthread(test, sbm_write_past_page_threadfn,
+ &data);
+ }
+
+ KUNIT_EXPECT_EQ(test, err, -EFAULT);
+ KUNIT_EXPECT_EQ(test, over->data.value, PASS);
+ KUNIT_EXPECT_EQ(test, over->nextpage, PASS);
+}
+
+/**************************************************************
+ * Memory write before output buffer.
+ *
+ * There is a guard page before the output buffer. Writes to
+ * this guard page should generate a page fault.
+ */
+
+static SBM_DEFINE_FUNC(write_before, struct data *, out)
+{
+ out[-1].value = FAIL;
+ barrier();
+ out[0].value = FAIL;
+ return 0;
+}
+
+static int sbm_write_before_threadfn(struct kunit *test,
+ struct thread_data *data)
+{
+ struct sbm sbm;
+ int err;
+
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, write_before,
+ SBM_COPY_OUT(&sbm, data->out, sizeof(*data->out)));
+ sbm_destroy(&sbm);
+ return err;
+}
+
+static void sbm_write_before(struct kunit *test)
+{
+ struct data out;
+ int err;
+
+ out.value = PASS;
+ if (IS_ENABLED(CONFIG_HAVE_ARCH_SBM)) {
+ struct sbm sbm;
+
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, write_before,
+ SBM_COPY_OUT(&sbm, &out, sizeof(out)));
+ KUNIT_EXPECT_EQ(test, sbm_error(&sbm), -EFAULT);
+ sbm_destroy(&sbm);
+ } else {
+ struct thread_data data;
+
+ data.out = &out;
+ err = run_sbm_kthread(test, sbm_write_before_threadfn, &data);
+ }
+
+ KUNIT_EXPECT_EQ(test, err, -EFAULT);
+ KUNIT_EXPECT_EQ(test, out.value, PASS);
+}
+
+/**************************************************************
+ * Memory write to kernel static data.
+ *
+ * Sandbox mode cannot write to a kernel static data.
+ */
+
+struct data static_data = { .value = FAIL };
+
+static void sbm_write_static(struct kunit *test)
+{
+ struct sbm sbm;
+ int err;
+
+ check_safe_sbm(test);
+
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, write, &static_data);
+ sbm_destroy(&sbm);
+
+ KUNIT_EXPECT_EQ(test, err, -EFAULT);
+ KUNIT_EXPECT_EQ(test, sbm_error(&sbm), -EFAULT);
+ KUNIT_EXPECT_EQ(test, static_data.value, FAIL);
+}
+
+/**************************************************************
+ * Memory write to kernel BSS.
+ *
+ * Sandbox mode cannot write to kernel BSS.
+ */
+
+struct data static_bss;
+
+static void sbm_write_bss(struct kunit *test)
+{
+ struct sbm sbm;
+ int err;
+
+ check_safe_sbm(test);
+
+ static_bss.value = FAIL;
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, write, &static_bss);
+ sbm_destroy(&sbm);
+
+ KUNIT_EXPECT_EQ(test, err, -EFAULT);
+ KUNIT_EXPECT_EQ(test, sbm_error(&sbm), -EFAULT);
+ KUNIT_EXPECT_EQ(test, static_bss.value, FAIL);
+}
+
+/**************************************************************
+ * Memory write to unrelated buffer.
+ *
+ * Sandbox mode cannot write to the wrong buffer.
+ */
+
+static void sbm_write_wrong(struct kunit *test)
+{
+ struct data *out;
+ struct sbm sbm;
+ int err;
+
+ check_safe_sbm(test);
+
+ out = kunit_kzalloc(test, sizeof(*out), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, out);
+ out->value = FAIL;
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, write, out);
+ sbm_destroy(&sbm);
+
+ KUNIT_EXPECT_EQ(test, err, -EFAULT);
+ KUNIT_EXPECT_EQ(test, sbm_error(&sbm), -EFAULT);
+ KUNIT_EXPECT_EQ(test, out->value, FAIL);
+}
+
+/**************************************************************
+ * Memory write to kernel stack.
+ *
+ * Sandbox mode runs on its own stack. The kernel stack cannot
+ * be modified.
+ */
+
+static void sbm_write_stack(struct kunit *test)
+{
+ struct data out;
+ struct sbm sbm;
+ int err;
+
+ check_safe_sbm(test);
+
+ out.value = FAIL;
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, write, &out);
+ sbm_destroy(&sbm);
+
+ KUNIT_EXPECT_EQ(test, err, -EFAULT);
+ KUNIT_EXPECT_EQ(test, sbm_error(&sbm), -EFAULT);
+ KUNIT_EXPECT_EQ(test, out.value, FAIL);
+}
+
+/**************************************************************
+ * Simple update of an input/output buffer.
+ *
+ * Verify that the input buffer is copied in and also back to the caller.
+ */
+
+static SBM_DEFINE_FUNC(update, struct data *, data)
+{
+ data->value ^= FAIL ^ PASS;
+ return 0;
+}
+
+static void sbm_update(struct kunit *test)
+{
+ struct sbm sbm;
+ struct data data;
+ int err;
+
+ data.value = FAIL;
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, update,
+ SBM_COPY_INOUT(&sbm, &data, sizeof(data)));
+ sbm_destroy(&sbm);
+
+ KUNIT_EXPECT_EQ(test, err, 0);
+ KUNIT_EXPECT_EQ(test, sbm_error(&sbm), 0);
+ KUNIT_EXPECT_EQ(test, data.value, PASS);
+}
+
+/**************************************************************
+ * Copy from input buffer to output buffer.
+ *
+ * Verify that sandbox mode can read from the input buffer and
+ * write to the output buffer.
+ */
+
+static int copy_value(const struct data *in, struct data *out)
+{
+ out->value = in->value;
+ return 0;
+}
+
+/*
+ * Define call helper and thunk explicitly to verify that this syntax also
+ * works.
+ */
+static SBM_DEFINE_CALL(copy_value, const struct data *, in,
+ struct data *, out);
+static SBM_DEFINE_THUNK(copy_value, const struct data *, in,
+ struct data *, out);
+
+static void sbm_copy_value(struct kunit *test)
+{
+ struct sbm sbm;
+ struct data in[1];
+ struct data out[1];
+ int err;
+
+ in[0].value = PASS;
+ out[0].value = FAIL;
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, copy_value,
+ SBM_COPY_IN(&sbm, in, sizeof(in)),
+ SBM_COPY_OUT(&sbm, out, sizeof(out)));
+ sbm_destroy(&sbm);
+
+ KUNIT_EXPECT_EQ(test, err, 0);
+ KUNIT_EXPECT_EQ(test, sbm_error(&sbm), 0);
+ KUNIT_EXPECT_EQ(test, out[0].value, PASS);
+}
+
+/**************************************************************
+ * Memory read past input buffer within the same page.
+ *
+ * The page beyond the input buffer is initialized to zero.
+ */
+
+static SBM_DEFINE_FUNC(read_past, const struct data *, in)
+{
+ return in[1].value;
+}
+
+static void sbm_read_past(struct kunit *test)
+{
+ struct sbm sbm;
+ struct data in[2];
+ int err;
+
+ in[0].value = PASS;
+ in[1].value = FAIL;
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, read_past,
+ SBM_COPY_IN(&sbm, &in[0], sizeof(in[0])));
+ sbm_destroy(&sbm);
+
+ KUNIT_EXPECT_EQ(test, err, 0);
+ KUNIT_EXPECT_EQ(test, sbm_error(&sbm), 0);
+}
+
+/**************************************************************
+ * Memory read from next page past input buffer.
+ *
+ * There is a guard page after the input buffer. Reading from
+ * that page should generate a page fault.
+ */
+
+static SBM_DEFINE_FUNC(read_past_page, const struct data *, in)
+{
+ const struct page_over *over = (const struct page_over *)in;
+
+ return over->nextpage;
+}
+
+static int sbm_read_past_page_threadfn(struct kunit *test,
+ struct thread_data *data)
+{
+ struct sbm sbm;
+ int err;
+
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, read_past_page,
+ SBM_COPY_IN(&sbm, data->in, sizeof(*data->in)));
+ sbm_destroy(&sbm);
+ return err;
+}
+
+static void sbm_read_past_page(struct kunit *test)
+{
+ struct page_over *over;
+ int err;
+
+ over = kunit_kzalloc(test, sizeof(*over), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, over);
+ over->data.value = PASS;
+ over->nextpage = FAIL;
+ if (IS_ENABLED(CONFIG_HAVE_ARCH_SBM)) {
+ struct sbm sbm;
+
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, read_past_page,
+ SBM_COPY_IN(&sbm, &over->data,
+ sizeof(over->data)));
+ KUNIT_EXPECT_EQ(test, sbm_error(&sbm), -EFAULT);
+ sbm_destroy(&sbm);
+ } else {
+ struct thread_data data;
+
+ data.in = &over->data;
+ err = run_sbm_kthread(test, sbm_read_past_page_threadfn, &data);
+ }
+
+ KUNIT_EXPECT_EQ(test, err, -EFAULT);
+}
+
+/**************************************************************
+ * Memory read before input buffer.
+ *
+ * There is a guard page before the input buffer. Reading from
+ * that page should generate a page fault.
+ */
+
+static SBM_DEFINE_FUNC(read_before, const struct data *, in)
+{
+ return in[-1].value;
+}
+
+static int sbm_read_before_threadfn(struct kunit *test,
+ struct thread_data *data)
+{
+ struct sbm sbm;
+ int err;
+
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, read_before,
+ SBM_COPY_IN(&sbm, data->in, sizeof(*data->in)));
+ sbm_destroy(&sbm);
+ return err;
+}
+
+static void sbm_read_before(struct kunit *test)
+{
+ struct data in;
+ int err;
+
+ in.value = PASS;
+ if (IS_ENABLED(CONFIG_HAVE_ARCH_SBM)) {
+ struct sbm sbm;
+
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, read_before,
+ SBM_COPY_IN(&sbm, &in, sizeof(in)));
+ KUNIT_EXPECT_EQ(test, sbm_error(&sbm), -EFAULT);
+ sbm_destroy(&sbm);
+ } else {
+ struct thread_data data;
+
+ data.in = &in;
+ err = run_sbm_kthread(test, sbm_read_before_threadfn, &data);
+ }
+
+ KUNIT_EXPECT_EQ(test, err, -EFAULT);
+}
+
+/**************************************************************
+ * Memory read from unrelated buffer.
+ *
+ * Sandbox mode cannot read from the wrong buffer.
+ */
+
+static SBM_DEFINE_FUNC(read_wrong, const struct data *, in)
+{
+ return in->value;
+}
+
+static void sbm_read_wrong(struct kunit *test)
+{
+ struct data *in;
+ struct sbm sbm;
+ int err;
+
+ check_safe_sbm(test);
+
+ in = kunit_kzalloc(test, sizeof(*in), GFP_KERNEL);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, in);
+ in->value = FAIL;
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, read_wrong, in);
+ sbm_destroy(&sbm);
+
+ KUNIT_EXPECT_EQ(test, err, -EFAULT);
+ KUNIT_EXPECT_EQ(test, sbm_error(&sbm), -EFAULT);
+}
+
+/**************************************************************
+ * Stack bottom.
+ *
+ * Sandbox mode can read from the bottom of the kernel stack.
+ * Verify that all of the kernel stack is mapped.
+ */
+
+static SBM_DEFINE_FUNC(stack_bottom)
+{
+ return *end_of_stack(current);
+}
+
+static void sbm_stack_bottom(struct kunit *test)
+{
+ struct sbm sbm;
+ unsigned long *bottom;
+ int err;
+
+ bottom = end_of_stack(current);
+ *bottom = PASS;
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, stack_bottom);
+ sbm_destroy(&sbm);
+
+ KUNIT_EXPECT_EQ(test, err, PASS);
+ KUNIT_EXPECT_EQ(test, sbm_error(&sbm), 0);
+ KUNIT_EXPECT_EQ(test, *bottom, PASS);
+}
+
+/**************************************************************
+ * Stack overflow.
+ *
+ * Sandbox mode cannot overflow the stack.
+ *
+ * This test is not safe without SBM arch hooks, because the kernel may panic
+ * when kernel stack overflow is detected.
+ */
+
+static noinline int kaboom(void)
+{
+ return 0;
+}
+
+static SBM_DEFINE_FUNC(stack_overflow)
+{
+ unsigned long old_sp = current_stack_pointer;
+ int err;
+
+ current_stack_pointer = (unsigned long)end_of_stack(current);
+ barrier();
+ err = kaboom();
+ current_stack_pointer = old_sp;
+ return err;
+}
+
+static void sbm_stack_overflow(struct kunit *test)
+{
+ struct sbm sbm;
+ int err;
+
+ check_safe_sbm(test);
+
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, stack_overflow);
+ sbm_destroy(&sbm);
+
+ KUNIT_EXPECT_EQ(test, err, -EFAULT);
+ KUNIT_EXPECT_EQ(test, sbm_error(&sbm), -EFAULT);
+}
+
+#ifdef CONFIG_X86_64
+
+/**************************************************************
+ * [X86-64] Non-canonical address.
+ *
+ * Sandbox mode recovers from a #GP exception. Test it by
+ * memory write to a non-canonical address.
+ */
+
+static void sbm_x86_64_gp(struct kunit *test)
+{
+ void *non_canonical;
+ struct sbm sbm;
+ int err;
+
+ check_safe_sbm(test);
+
+ non_canonical = (void *)(1ULL << 63);
+ sbm_init(&sbm);
+ err = sbm_call(&sbm, write, non_canonical);
+ sbm_destroy(&sbm);
+
+ KUNIT_EXPECT_EQ(test, err, -EFAULT);
+ KUNIT_EXPECT_EQ(test, sbm_error(&sbm), -EFAULT);
+}
+
+#endif
+
+/**************************************************************
+ * Test suite metadata.
+ */
+
+static struct kunit_case sbm_test_cases[] = {
+ KUNIT_CASE(sbm_write),
+ KUNIT_CASE(sbm_write_past),
+ KUNIT_CASE(sbm_write_past_page),
+ KUNIT_CASE(sbm_write_before),
+ KUNIT_CASE(sbm_write_static),
+ KUNIT_CASE(sbm_write_bss),
+ KUNIT_CASE(sbm_write_wrong),
+ KUNIT_CASE(sbm_write_stack),
+ KUNIT_CASE(sbm_copy_value),
+ KUNIT_CASE(sbm_read_past),
+ KUNIT_CASE(sbm_read_past_page),
+ KUNIT_CASE(sbm_read_before),
+ KUNIT_CASE(sbm_read_wrong),
+ KUNIT_CASE(sbm_update),
+ KUNIT_CASE(sbm_stack_bottom),
+ KUNIT_CASE(sbm_stack_overflow),
+#ifdef CONFIG_X86_64
+ KUNIT_CASE(sbm_x86_64_gp),
+#endif
+ {}
+};
+
+static struct kunit_suite sbm_test_suite = {
+ .name = "sandbox_mode",
+ .test_cases = sbm_test_cases,
+};
+
+kunit_test_suites(&sbm_test_suite);
+
+MODULE_LICENSE("GPL");
--
2.34.1



2024-02-15 19:16:04

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v1 4/5] sbm: SandBox Mode KUnit test suite

Hi Petr,

kernel test robot noticed the following build errors:

[auto build test ERROR on akpm-mm/mm-everything]
[also build test ERROR on linus/master v6.8-rc4 next-20240215]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Petr-Tesarik/sbm-SandBox-Mode-core-data-types-and-functions/20240214-193528
base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link: https://lore.kernel.org/r/20240214113035.2117-5-petrtesarik%40huaweicloud.com
patch subject: [PATCH v1 4/5] sbm: SandBox Mode KUnit test suite
config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20240216/[email protected]/config)
compiler: clang version 19.0.0git (https://github.com/llvm/llvm-project 1c10821022f1799452065fb57474e894e2562b7f)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240216/[email protected]/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 <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

All errors (new ones prefixed by >>):

>> kernel/sbm_test.c:648:25: error: use of undeclared identifier 'current_stack_pointer'
648 | unsigned long old_sp = current_stack_pointer;
| ^
kernel/sbm_test.c:651:2: error: use of undeclared identifier 'current_stack_pointer'
651 | current_stack_pointer = (unsigned long)end_of_stack(current);
| ^
kernel/sbm_test.c:654:2: error: use of undeclared identifier 'current_stack_pointer'
654 | current_stack_pointer = old_sp;
| ^
3 errors generated.


vim +/current_stack_pointer +648 kernel/sbm_test.c

645
646 static SBM_DEFINE_FUNC(stack_overflow)
647 {
> 648 unsigned long old_sp = current_stack_pointer;
649 int err;
650
651 current_stack_pointer = (unsigned long)end_of_stack(current);
652 barrier();
653 err = kaboom();
654 current_stack_pointer = old_sp;
655 return err;
656 }
657

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

2024-02-16 01:55:07

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH v1 4/5] sbm: SandBox Mode KUnit test suite

Hi Petr,

kernel test robot noticed the following build warnings:

[auto build test WARNING on akpm-mm/mm-everything]
[also build test WARNING on linus/master v6.8-rc4 next-20240215]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url: https://github.com/intel-lab-lkp/linux/commits/Petr-Tesarik/sbm-SandBox-Mode-core-data-types-and-functions/20240214-193528
base: https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git mm-everything
patch link: https://lore.kernel.org/r/20240214113035.2117-5-petrtesarik%40huaweicloud.com
patch subject: [PATCH v1 4/5] sbm: SandBox Mode KUnit test suite
config: mips-randconfig-r121-20240215 (https://download.01.org/0day-ci/archive/20240216/[email protected]/config)
compiler: mips-linux-gcc (GCC) 13.2.0
reproduce: (https://download.01.org/0day-ci/archive/20240216/[email protected]/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 <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

sparse warnings: (new ones prefixed by >>)
>> kernel/sbm_test.c:300:13: sparse: sparse: symbol 'static_bss' was not declared. Should it be static?

vim +/static_bss +300 kernel/sbm_test.c

293
294 /**************************************************************
295 * Memory write to kernel BSS.
296 *
297 * Sandbox mode cannot write to kernel BSS.
298 */
299
> 300 struct data static_bss;
301

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki