Skip to content

Commit 2959a5f

Browse files
jinb-parktorvalds
authored andcommitted
mm: add arch-independent testcases for RODATA
This patch makes arch-independent testcases for RODATA. Both x86 and x86_64 already have testcases for RODATA, But they are arch-specific because using inline assembly directly. And cacheflush.h is not a suitable location for rodata-test related things. Since they were in cacheflush.h, If someone change the state of CONFIG_DEBUG_RODATA_TEST, It cause overhead of kernel build. To solve the above issues, write arch-independent testcases and move it to shared location. [[email protected]: fix config dependency] Link: http://lkml.kernel.org/r/20170209131625.GA16954@pjb1027-Latitude-E5410 Link: http://lkml.kernel.org/r/20170129105436.GA9303@pjb1027-Latitude-E5410 Signed-off-by: Jinbum Park <[email protected]> Acked-by: Kees Cook <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Arjan van de Ven <[email protected]> Cc: Laura Abbott <[email protected]> Cc: Russell King <[email protected]> Cc: Valentin Rothberg <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 8d85063 commit 2959a5f

File tree

11 files changed

+90
-105
lines changed

11 files changed

+90
-105
lines changed

arch/x86/Kconfig.debug

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -74,14 +74,6 @@ config EFI_PGT_DUMP
7474
issues with the mapping of the EFI runtime regions into that
7575
table.
7676

77-
config DEBUG_RODATA_TEST
78-
bool "Testcase for the marking rodata read-only"
79-
default y
80-
---help---
81-
This option enables a testcase for the setting rodata read-only
82-
as well as for the change_page_attr() infrastructure.
83-
If in doubt, say "N"
84-
8577
config DEBUG_WX
8678
bool "Warn on W+X mappings at boot"
8779
select X86_PTDUMP_CORE

arch/x86/include/asm/cacheflush.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,18 +90,8 @@ void clflush_cache_range(void *addr, unsigned int size);
9090

9191
#define mmio_flush_range(addr, size) clflush_cache_range(addr, size)
9292

93-
extern const int rodata_test_data;
9493
extern int kernel_set_to_readonly;
9594
void set_kernel_text_rw(void);
9695
void set_kernel_text_ro(void);
9796

98-
#ifdef CONFIG_DEBUG_RODATA_TEST
99-
int rodata_test(void);
100-
#else
101-
static inline int rodata_test(void)
102-
{
103-
return 0;
104-
}
105-
#endif
106-
10797
#endif /* _ASM_X86_CACHEFLUSH_H */

arch/x86/kernel/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ obj-$(CONFIG_HPET_TIMER) += hpet.o
100100
obj-$(CONFIG_APB_TIMER) += apb_timer.o
101101

102102
obj-$(CONFIG_AMD_NB) += amd_nb.o
103-
obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o
104103
obj-$(CONFIG_DEBUG_NMI_SELFTEST) += nmi_selftest.o
105104

106105
obj-$(CONFIG_KVM_GUEST) += kvm.o kvmclock.o

arch/x86/kernel/test_rodata.c

Lines changed: 0 additions & 75 deletions
This file was deleted.

arch/x86/mm/init_32.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -864,9 +864,6 @@ static noinline int do_test_wp_bit(void)
864864
return flag;
865865
}
866866

867-
const int rodata_test_data = 0xC3;
868-
EXPORT_SYMBOL_GPL(rodata_test_data);
869-
870867
int kernel_set_to_readonly __read_mostly;
871868

872869
void set_kernel_text_rw(void)
@@ -939,7 +936,6 @@ void mark_rodata_ro(void)
939936
set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
940937
printk(KERN_INFO "Write protecting the kernel read-only data: %luk\n",
941938
size >> 10);
942-
rodata_test();
943939

944940
#ifdef CONFIG_CPA_DEBUG
945941
printk(KERN_INFO "Testing CPA: undo %lx-%lx\n", start, start + size);

arch/x86/mm/init_64.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1000,9 +1000,6 @@ void __init mem_init(void)
10001000
mem_init_print_info(NULL);
10011001
}
10021002

1003-
const int rodata_test_data = 0xC3;
1004-
EXPORT_SYMBOL_GPL(rodata_test_data);
1005-
10061003
int kernel_set_to_readonly;
10071004

10081005
void set_kernel_text_rw(void)
@@ -1071,8 +1068,6 @@ void mark_rodata_ro(void)
10711068
all_end = roundup((unsigned long)_brk_end, PMD_SIZE);
10721069
set_memory_nx(text_end, (all_end - text_end) >> PAGE_SHIFT);
10731070

1074-
rodata_test();
1075-
10761071
#ifdef CONFIG_CPA_DEBUG
10771072
printk(KERN_INFO "Testing CPA: undo %lx-%lx\n", start, end);
10781073
set_memory_rw(start, (end-start) >> PAGE_SHIFT);

include/linux/rodata_test.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
* rodata_test.h: functional test for mark_rodata_ro function
3+
*
4+
* (C) Copyright 2008 Intel Corporation
5+
* Author: Arjan van de Ven <[email protected]>
6+
*
7+
* This program is free software; you can redistribute it and/or
8+
* modify it under the terms of the GNU General Public License
9+
* as published by the Free Software Foundation; version 2
10+
* of the License.
11+
*/
12+
13+
#ifndef _RODATA_TEST_H
14+
#define _RODATA_TEST_H
15+
16+
#ifdef CONFIG_DEBUG_RODATA_TEST
17+
extern const int rodata_test_data;
18+
void rodata_test(void);
19+
#else
20+
static inline void rodata_test(void) {}
21+
#endif
22+
23+
#endif /* _RODATA_TEST_H */

init/main.c

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@
8282
#include <linux/proc_ns.h>
8383
#include <linux/io.h>
8484
#include <linux/cache.h>
85+
#include <linux/rodata_test.h>
8586

8687
#include <asm/io.h>
8788
#include <asm/bugs.h>
@@ -935,9 +936,10 @@ __setup("rodata=", set_debug_rodata);
935936
#ifdef CONFIG_STRICT_KERNEL_RWX
936937
static void mark_readonly(void)
937938
{
938-
if (rodata_enabled)
939+
if (rodata_enabled) {
939940
mark_rodata_ro();
940-
else
941+
rodata_test();
942+
} else
941943
pr_info("Kernel memory protection disabled.\n");
942944
}
943945
#else

mm/Kconfig.debug

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,9 @@ config DEBUG_PAGE_REF
9090
careful when enabling this feature because it adds about 30 KB to the
9191
kernel code. However the runtime performance overhead is virtually
9292
nil until the tracepoints are actually enabled.
93+
94+
config DEBUG_RODATA_TEST
95+
bool "Testcase for the marking rodata read-only"
96+
depends on STRICT_KERNEL_RWX
97+
---help---
98+
This option enables a testcase for the setting rodata read-only.

mm/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ obj-$(CONFIG_MEMORY_FAILURE) += memory-failure.o
8585
obj-$(CONFIG_HWPOISON_INJECT) += hwpoison-inject.o
8686
obj-$(CONFIG_DEBUG_KMEMLEAK) += kmemleak.o
8787
obj-$(CONFIG_DEBUG_KMEMLEAK_TEST) += kmemleak-test.o
88+
obj-$(CONFIG_DEBUG_RODATA_TEST) += rodata_test.o
8889
obj-$(CONFIG_PAGE_OWNER) += page_owner.o
8990
obj-$(CONFIG_CLEANCACHE) += cleancache.o
9091
obj-$(CONFIG_MEMORY_ISOLATION) += page_isolation.o

mm/rodata_test.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* rodata_test.c: functional test for mark_rodata_ro function
3+
*
4+
* (C) Copyright 2008 Intel Corporation
5+
* Author: Arjan van de Ven <[email protected]>
6+
*
7+
* This program is free software; you can redistribute it and/or
8+
* modify it under the terms of the GNU General Public License
9+
* as published by the Free Software Foundation; version 2
10+
* of the License.
11+
*/
12+
#include <linux/uaccess.h>
13+
#include <asm/sections.h>
14+
15+
const int rodata_test_data = 0xC3;
16+
EXPORT_SYMBOL_GPL(rodata_test_data);
17+
18+
void rodata_test(void)
19+
{
20+
unsigned long start, end;
21+
int zero = 0;
22+
23+
/* test 1: read the value */
24+
/* If this test fails, some previous testrun has clobbered the state */
25+
if (!rodata_test_data) {
26+
pr_err("rodata_test: test 1 fails (start data)\n");
27+
return;
28+
}
29+
30+
/* test 2: write to the variable; this should fault */
31+
if (!probe_kernel_write((void *)&rodata_test_data,
32+
(void *)&zero, sizeof(zero))) {
33+
pr_err("rodata_test: test data was not read only\n");
34+
return;
35+
}
36+
37+
/* test 3: check the value hasn't changed */
38+
if (rodata_test_data == zero) {
39+
pr_err("rodata_test: test data was changed\n");
40+
return;
41+
}
42+
43+
/* test 4: check if the rodata section is PAGE_SIZE aligned */
44+
start = (unsigned long)__start_rodata;
45+
end = (unsigned long)__end_rodata;
46+
if (start & (PAGE_SIZE - 1)) {
47+
pr_err("rodata_test: start of .rodata is not page size aligned\n");
48+
return;
49+
}
50+
if (end & (PAGE_SIZE - 1)) {
51+
pr_err("rodata_test: end of .rodata is not page size aligned\n");
52+
return;
53+
}
54+
55+
pr_info("rodata_test: all tests were successful\n");
56+
}

0 commit comments

Comments
 (0)