Refactor the test cases, in preparation for using them also for testing __wr_after_init memory. Signed-off-by: Igor Stoppa <igor.stoppa@xxxxxxxxxx> CC: Andy Lutomirski <luto@xxxxxxxxxxxxxx> CC: Nadav Amit <nadav.amit@xxxxxxxxx> CC: Matthew Wilcox <willy@xxxxxxxxxxxxx> CC: Peter Zijlstra <peterz@xxxxxxxxxxxxx> CC: Kees Cook <keescook@xxxxxxxxxxxx> CC: Dave Hansen <dave.hansen@xxxxxxxxxxxxxxx> CC: linux-integrity@xxxxxxxxxxxxxxx CC: kernel-hardening@xxxxxxxxxxxxxxxxxx CC: linux-mm@xxxxxxxxx CC: linux-kernel@xxxxxxxxxxxxxxx --- mm/rodata_test.c | 48 ++++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/mm/rodata_test.c b/mm/rodata_test.c index d908c8769b48..3c1e515ca9b1 100644 --- a/mm/rodata_test.c +++ b/mm/rodata_test.c @@ -14,44 +14,52 @@ #include <linux/uaccess.h> #include <asm/sections.h> -static const int rodata_test_data = 0xC3; +#define INIT_TEST_VAL 0xC3 -void rodata_test(void) +static const int rodata_test_data = INIT_TEST_VAL; + +static bool test_data(char *data_type, const int *data, + unsigned long start, unsigned long end) { - unsigned long start, end; int zero = 0; /* test 1: read the value */ /* If this test fails, some previous testrun has clobbered the state */ - if (!rodata_test_data) { - pr_err("test 1 fails (start data)\n"); - return; + if (*data != INIT_TEST_VAL) { + pr_err("%s: test 1 fails (init data value)\n", data_type); + return false; } /* test 2: write to the variable; this should fault */ - if (!probe_kernel_write((void *)&rodata_test_data, - (void *)&zero, sizeof(zero))) { - pr_err("test data was not read only\n"); - return; + if (!probe_kernel_write((void *)data, (void *)&zero, sizeof(zero))) { + pr_err("%s: test data was not read only\n", data_type); + return false; } /* test 3: check the value hasn't changed */ - if (rodata_test_data == zero) { - pr_err("test data was changed\n"); - return; + if (*data != INIT_TEST_VAL) { + pr_err("%s: test data was changed\n", data_type); + return false; } /* test 4: check if the rodata section is PAGE_SIZE aligned */ - start = (unsigned long)__start_rodata; - end = (unsigned long)__end_rodata; if (start & (PAGE_SIZE - 1)) { - pr_err("start of .rodata is not page size aligned\n"); - return; + pr_err("%s: start of data is not page size aligned\n", + data_type); + return false; } if (end & (PAGE_SIZE - 1)) { - pr_err("end of .rodata is not page size aligned\n"); - return; + pr_err("%s: end of data is not page size aligned\n", + data_type); + return false; } + return true; +} - pr_info("all tests were successful\n"); +void rodata_test(void) +{ + if (test_data("rodata", &rodata_test_data, + (unsigned long)&__start_rodata, + (unsigned long)&__end_rodata)) + pr_info("all tests were successful\n"); } -- 2.19.1