forked from mirrors/linux
		
	x86/mm: Remove CONFIG_DEBUG_NX_TEST
CONFIG_DEBUG_NX_TEST has been broken since CONFIG_DEBUG_SET_MODULE_RONX=y was added in v2.6.37 via:84e1c6bb38("x86: Add RO/NX protection for loadable kernel modules") since the exception table was then made read-only. Additionally, the manually constructed extables were never fixed when relative extables were introduced in v3.5 via:706276543b("x86, extable: Switch to relative exception table entries") However, relative extables won't work for test_nx.c, since test instruction memory areas may be more than INT_MAX away from an executable fixup (e.g. stack and heap too far away from executable memory with the fixup). Since clearly no one has been using this code for a while now, and similar tests exist in LKDTM, this should just be removed entirely. Signed-off-by: Kees Cook <keescook@chromium.org> Cc: Andy Lutomirski <luto@kernel.org> Cc: Arjan van de Ven <arjan@linux.intel.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Jinbum Park <jinb.park7@gmail.com> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Link: http://lkml.kernel.org/r/20170131003711.GA74048@beast Signed-off-by: Ingo Molnar <mingo@kernel.org>
This commit is contained in:
		
							parent
							
								
									459fbe0069
								
							
						
					
					
						commit
						3ad38ceb27
					
				
					 3 changed files with 0 additions and 182 deletions
				
			
		|  | @ -120,14 +120,6 @@ config DEBUG_SET_MODULE_RONX | |||
| 	  against certain classes of kernel exploits. | ||||
| 	  If in doubt, say "N". | ||||
| 
 | ||||
| config DEBUG_NX_TEST | ||||
| 	tristate "Testcase for the NX non-executable stack feature" | ||||
| 	depends on DEBUG_KERNEL && m | ||||
| 	---help--- | ||||
| 	  This option enables a testcase for the CPU NX capability | ||||
| 	  and the software setup of this feature. | ||||
| 	  If in doubt, say "N" | ||||
| 
 | ||||
| config DOUBLEFAULT | ||||
| 	default y | ||||
| 	bool "Enable doublefault exception handler" if EXPERT | ||||
|  |  | |||
|  | @ -101,7 +101,6 @@ obj-$(CONFIG_APB_TIMER)		+= apb_timer.o | |||
| 
 | ||||
| obj-$(CONFIG_AMD_NB)		+= amd_nb.o | ||||
| obj-$(CONFIG_DEBUG_RODATA_TEST)	+= test_rodata.o | ||||
| obj-$(CONFIG_DEBUG_NX_TEST)	+= test_nx.o | ||||
| obj-$(CONFIG_DEBUG_NMI_SELFTEST) += nmi_selftest.o | ||||
| 
 | ||||
| obj-$(CONFIG_KVM_GUEST)		+= kvm.o kvmclock.o | ||||
|  |  | |||
|  | @ -1,173 +0,0 @@ | |||
| /*
 | ||||
|  * test_nx.c: functional test for NX functionality | ||||
|  * | ||||
|  * (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/module.h> | ||||
| #include <linux/sort.h> | ||||
| #include <linux/slab.h> | ||||
| 
 | ||||
| #include <linux/uaccess.h> | ||||
| #include <asm/asm.h> | ||||
| 
 | ||||
| extern int rodata_test_data; | ||||
| 
 | ||||
| /*
 | ||||
|  * This file checks 4 things: | ||||
|  * 1) Check if the stack is not executable | ||||
|  * 2) Check if kmalloc memory is not executable | ||||
|  * 3) Check if the .rodata section is not executable | ||||
|  * 4) Check if the .data section of a module is not executable | ||||
|  * | ||||
|  * To do this, the test code tries to execute memory in stack/kmalloc/etc, | ||||
|  * and then checks if the expected trap happens. | ||||
|  * | ||||
|  * Sadly, this implies having a dynamic exception handling table entry. | ||||
|  * ... which can be done (and will make Rusty cry)... but it can only | ||||
|  * be done in a stand-alone module with only 1 entry total. | ||||
|  * (otherwise we'd have to sort and that's just too messy) | ||||
|  */ | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|  * We want to set up an exception handling point on our stack, | ||||
|  * which means a variable value. This function is rather dirty | ||||
|  * and walks the exception table of the module, looking for a magic | ||||
|  * marker and replaces it with a specific function. | ||||
|  */ | ||||
| static void fudze_exception_table(void *marker, void *new) | ||||
| { | ||||
| 	struct module *mod = THIS_MODULE; | ||||
| 	struct exception_table_entry *extable; | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * Note: This module has only 1 exception table entry, | ||||
| 	 * so searching and sorting is not needed. If that changes, | ||||
| 	 * this would be the place to search and re-sort the exception | ||||
| 	 * table. | ||||
| 	 */ | ||||
| 	if (mod->num_exentries > 1) { | ||||
| 		printk(KERN_ERR "test_nx: too many exception table entries!\n"); | ||||
| 		printk(KERN_ERR "test_nx: test results are not reliable.\n"); | ||||
| 		return; | ||||
| 	} | ||||
| 	extable = (struct exception_table_entry *)mod->extable; | ||||
| 	extable[0].insn = (unsigned long)new; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /*
 | ||||
|  * exception tables get their symbols translated so we need | ||||
|  * to use a fake function to put in there, which we can then | ||||
|  * replace at runtime. | ||||
|  */ | ||||
| void foo_label(void); | ||||
| 
 | ||||
| /*
 | ||||
|  * returns 0 for not-executable, negative for executable | ||||
|  * | ||||
|  * Note: we cannot allow this function to be inlined, because | ||||
|  * that would give us more than 1 exception table entry. | ||||
|  * This in turn would break the assumptions above. | ||||
|  */ | ||||
| static noinline int test_address(void *address) | ||||
| { | ||||
| 	unsigned long result; | ||||
| 
 | ||||
| 	/* Set up an exception table entry for our address */ | ||||
| 	fudze_exception_table(&foo_label, address); | ||||
| 	result = 1; | ||||
| 	asm volatile( | ||||
| 		"foo_label:\n" | ||||
| 		"0:	call *%[fake_code]\n" | ||||
| 		"1:\n" | ||||
| 		".section .fixup,\"ax\"\n" | ||||
| 		"2:	mov %[zero], %[rslt]\n" | ||||
| 		"	ret\n" | ||||
| 		".previous\n" | ||||
| 		_ASM_EXTABLE(0b,2b) | ||||
| 		: [rslt] "=r" (result) | ||||
| 		: [fake_code] "r" (address), [zero] "r" (0UL), "0" (result) | ||||
| 	); | ||||
| 	/* change the exception table back for the next round */ | ||||
| 	fudze_exception_table(address, &foo_label); | ||||
| 
 | ||||
| 	if (result) | ||||
| 		return -ENODEV; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| static unsigned char test_data = 0xC3; /* 0xC3 is the opcode for "ret" */ | ||||
| 
 | ||||
| static int test_NX(void) | ||||
| { | ||||
| 	int ret = 0; | ||||
| 	/* 0xC3 is the opcode for "ret" */ | ||||
| 	char stackcode[] = {0xC3, 0x90, 0 }; | ||||
| 	char *heap; | ||||
| 
 | ||||
| 	test_data = 0xC3; | ||||
| 
 | ||||
| 	printk(KERN_INFO "Testing NX protection\n"); | ||||
| 
 | ||||
| 	/* Test 1: check if the stack is not executable */ | ||||
| 	if (test_address(&stackcode)) { | ||||
| 		printk(KERN_ERR "test_nx: stack was executable\n"); | ||||
| 		ret = -ENODEV; | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| 	/* Test 2: Check if the heap is executable */ | ||||
| 	heap = kmalloc(64, GFP_KERNEL); | ||||
| 	if (!heap) | ||||
| 		return -ENOMEM; | ||||
| 	heap[0] = 0xC3; /* opcode for "ret" */ | ||||
| 
 | ||||
| 	if (test_address(heap)) { | ||||
| 		printk(KERN_ERR "test_nx: heap was executable\n"); | ||||
| 		ret = -ENODEV; | ||||
| 	} | ||||
| 	kfree(heap); | ||||
| 
 | ||||
| 	/*
 | ||||
| 	 * The following 2 tests currently fail, this needs to get fixed | ||||
| 	 * Until then, don't run them to avoid too many people getting scared | ||||
| 	 * by the error message | ||||
| 	 */ | ||||
| 
 | ||||
| 	/* Test 3: Check if the .rodata section is executable */ | ||||
| 	if (rodata_test_data != 0xC3) { | ||||
| 		printk(KERN_ERR "test_nx: .rodata marker has invalid value\n"); | ||||
| 		ret = -ENODEV; | ||||
| 	} else if (test_address(&rodata_test_data)) { | ||||
| 		printk(KERN_ERR "test_nx: .rodata section is executable\n"); | ||||
| 		ret = -ENODEV; | ||||
| 	} | ||||
| 
 | ||||
| #if 0 | ||||
| 	/* Test 4: Check if the .data section of a module is executable */ | ||||
| 	if (test_address(&test_data)) { | ||||
| 		printk(KERN_ERR "test_nx: .data section is executable\n"); | ||||
| 		ret = -ENODEV; | ||||
| 	} | ||||
| 
 | ||||
| #endif | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| static void test_exit(void) | ||||
| { | ||||
| } | ||||
| 
 | ||||
| module_init(test_NX); | ||||
| module_exit(test_exit); | ||||
| MODULE_LICENSE("GPL"); | ||||
| MODULE_DESCRIPTION("Testcase for the NX infrastructure"); | ||||
| MODULE_AUTHOR("Arjan van de Ven <arjan@linux.intel.com>"); | ||||
		Loading…
	
		Reference in a new issue
	
	 Kees Cook
						Kees Cook