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. [jinb.park7@gmail.com: 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 <jinb.park7@gmail.com> Acked-by: Kees Cook <keescook@chromium.org> Cc: Ingo Molnar <mingo@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Arjan van de Ven <arjan@linux.intel.com> Cc: Laura Abbott <labbott@redhat.com> Cc: Russell King <linux@armlinux.org.uk> Cc: Valentin Rothberg <valentinrothberg@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>tirimbino
parent
8d85063adb
commit
2959a5f726
@ -1,75 +0,0 @@ |
||||
/*
|
||||
* test_rodata.c: functional test for mark_rodata_ro function |
||||
* |
||||
* (C) Copyright 2008 Intel Corporation |
||||
* Author: Arjan van de Ven <arjan@linux.intel.com> |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License |
||||
* as published by the Free Software Foundation; version 2 |
||||
* of the License. |
||||
*/ |
||||
#include <asm/cacheflush.h> |
||||
#include <asm/sections.h> |
||||
#include <asm/asm.h> |
||||
|
||||
int rodata_test(void) |
||||
{ |
||||
unsigned long result; |
||||
unsigned long start, end; |
||||
|
||||
/* test 1: read the value */ |
||||
/* If this test fails, some previous testrun has clobbered the state */ |
||||
if (!rodata_test_data) { |
||||
printk(KERN_ERR "rodata_test: test 1 fails (start data)\n"); |
||||
return -ENODEV; |
||||
} |
||||
|
||||
/* test 2: write to the variable; this should fault */ |
||||
/*
|
||||
* If this test fails, we managed to overwrite the data |
||||
* |
||||
* This is written in assembly to be able to catch the |
||||
* exception that is supposed to happen in the correct |
||||
* case |
||||
*/ |
||||
|
||||
result = 1; |
||||
asm volatile( |
||||
"0: mov %[zero],(%[rodata_test])\n" |
||||
" mov %[zero], %[rslt]\n" |
||||
"1:\n" |
||||
".section .fixup,\"ax\"\n" |
||||
"2: jmp 1b\n" |
||||
".previous\n" |
||||
_ASM_EXTABLE(0b,2b) |
||||
: [rslt] "=r" (result) |
||||
: [rodata_test] "r" (&rodata_test_data), [zero] "r" (0UL) |
||||
); |
||||
|
||||
|
||||
if (!result) { |
||||
printk(KERN_ERR "rodata_test: test data was not read only\n"); |
||||
return -ENODEV; |
||||
} |
||||
|
||||
/* test 3: check the value hasn't changed */ |
||||
/* If this test fails, we managed to overwrite the data */ |
||||
if (!rodata_test_data) { |
||||
printk(KERN_ERR "rodata_test: Test 3 fails (end data)\n"); |
||||
return -ENODEV; |
||||
} |
||||
/* test 4: check if the rodata section is 4Kb aligned */ |
||||
start = (unsigned long)__start_rodata; |
||||
end = (unsigned long)__end_rodata; |
||||
if (start & (PAGE_SIZE - 1)) { |
||||
printk(KERN_ERR "rodata_test: .rodata is not 4k aligned\n"); |
||||
return -ENODEV; |
||||
} |
||||
if (end & (PAGE_SIZE - 1)) { |
||||
printk(KERN_ERR "rodata_test: .rodata end is not 4k aligned\n"); |
||||
return -ENODEV; |
||||
} |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,23 @@ |
||||
/*
|
||||
* rodata_test.h: functional test for mark_rodata_ro function |
||||
* |
||||
* (C) Copyright 2008 Intel Corporation |
||||
* Author: Arjan van de Ven <arjan@linux.intel.com> |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License |
||||
* as published by the Free Software Foundation; version 2 |
||||
* of the License. |
||||
*/ |
||||
|
||||
#ifndef _RODATA_TEST_H |
||||
#define _RODATA_TEST_H |
||||
|
||||
#ifdef CONFIG_DEBUG_RODATA_TEST |
||||
extern const int rodata_test_data; |
||||
void rodata_test(void); |
||||
#else |
||||
static inline void rodata_test(void) {} |
||||
#endif |
||||
|
||||
#endif /* _RODATA_TEST_H */ |
@ -0,0 +1,56 @@ |
||||
/*
|
||||
* rodata_test.c: functional test for mark_rodata_ro function |
||||
* |
||||
* (C) Copyright 2008 Intel Corporation |
||||
* Author: Arjan van de Ven <arjan@linux.intel.com> |
||||
* |
||||
* This program is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU General Public License |
||||
* as published by the Free Software Foundation; version 2 |
||||
* of the License. |
||||
*/ |
||||
#include <linux/uaccess.h> |
||||
#include <asm/sections.h> |
||||
|
||||
const int rodata_test_data = 0xC3; |
||||
EXPORT_SYMBOL_GPL(rodata_test_data); |
||||
|
||||
void rodata_test(void) |
||||
{ |
||||
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("rodata_test: test 1 fails (start data)\n"); |
||||
return; |
||||
} |
||||
|
||||
/* test 2: write to the variable; this should fault */ |
||||
if (!probe_kernel_write((void *)&rodata_test_data, |
||||
(void *)&zero, sizeof(zero))) { |
||||
pr_err("rodata_test: test data was not read only\n"); |
||||
return; |
||||
} |
||||
|
||||
/* test 3: check the value hasn't changed */ |
||||
if (rodata_test_data == zero) { |
||||
pr_err("rodata_test: test data was changed\n"); |
||||
return; |
||||
} |
||||
|
||||
/* 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("rodata_test: start of .rodata is not page size aligned\n"); |
||||
return; |
||||
} |
||||
if (end & (PAGE_SIZE - 1)) { |
||||
pr_err("rodata_test: end of .rodata is not page size aligned\n"); |
||||
return; |
||||
} |
||||
|
||||
pr_info("rodata_test: all tests were successful\n"); |
||||
} |
Loading…
Reference in new issue