From 948f984df52511bb0efa5c026813b0c34de43aa0 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Tue, 20 May 2008 14:39:25 +0300 Subject: core, x86: make LIST_POISON less deadly The list macros use LIST_POISON1 and LIST_POISON2 as undereferencable pointers in order to trap erronous use of freed list_heads. Unfortunately userspace can arrange for those pointers to actually be dereferencable, potentially turning an oops to an expolit. To avoid this allow architectures (currently x86_64 only) to override the default values for these pointers with truly-undereferencable values. This is easy on x86_64 as the virtual address space is large and contains permanently unmapped ranges. Other 64-bit architectures will likely find similar unmapped ranges. Signed-off-by: Avi Kivity Signed-off-by: Ingo Molnar --- arch/x86/Kconfig | 5 +++++ include/linux/poison.h | 10 ++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index fe361ae7ef2f..e21cc33b794a 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1021,6 +1021,11 @@ config ARCH_MEMORY_PROBE def_bool X86_64 depends on MEMORY_HOTPLUG +config ILLEGAL_POINTER_VALUE + hex + default 0 if X86_32 + default 0xffffc10000000000 if X86_64 + source "mm/Kconfig" config HIGHPTE diff --git a/include/linux/poison.h b/include/linux/poison.h index 9f31683728fd..0d105a56e668 100644 --- a/include/linux/poison.h +++ b/include/linux/poison.h @@ -1,14 +1,20 @@ #ifndef _LINUX_POISON_H #define _LINUX_POISON_H +#ifdef CONFIG_ILLEGAL_POINTER_VALUE +#define POISON_POINTER_DELTA CONFIG_ILLEGAL_POINTER_VALUE +#else +#define POISON_POINTER_DELTA 0L +#endif + /********** include/linux/list.h **********/ /* * These are non-NULL pointers that will result in page faults * under normal circumstances, used to verify that nobody uses * non-initialized list entries. */ -#define LIST_POISON1 ((void *) 0x00100100) -#define LIST_POISON2 ((void *) 0x00200200) +#define LIST_POISON1 ((void *) 0x00100100 + POISON_POINTER_DELTA) +#define LIST_POISON2 ((void *) 0x00200200 + POISON_POINTER_DELTA) /********** include/linux/timer.h **********/ /* -- cgit v1.2.3 From d23db9bbd91baaa1b22e7839e1e932bc6ae0582b Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Mon, 14 Jul 2008 18:03:27 +0200 Subject: x86: change LIST_POISON to 0xdead000000000000 Linus observed: | > + default 0xffffc10000000000 if X86_64 | | This looks like a singularly bad pointer value on x86-64. | | Why not pick something that is *guaranteed* to fault? The above looks like | any future setup that supports 41 bits of addressing and has extended the | page tables (yes, it will happen eventually) will find that to be a | perfectly valid address? | | It's also visually confusing, since it's visually very close to a real | kernel pointer too. Correct - so change the poison value to 0xdead000000000000. Acked-by: Linus Torvalds Signed-off-by: Ingo Molnar --- arch/x86/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index f09b3e5d808d..0dbd040bd654 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -1022,7 +1022,7 @@ config ARCH_MEMORY_PROBE config ILLEGAL_POINTER_VALUE hex default 0 if X86_32 - default 0xffffc10000000000 if X86_64 + default 0xdead000000000000 if X86_64 source "mm/Kconfig" -- cgit v1.2.3 From d31ec1c47b10e268794e7b739b2009ac6a19eb8b Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 22 Jul 2008 09:40:43 +0200 Subject: poison-pointers: clean up, add comments - remove stray 'L' (noticed by Andrew Morton) - add more comments about the purpose of this change - fix spelling (noticed by Andrew Morton) Signed-off-by: Ingo Molnar --- include/linux/poison.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/include/linux/poison.h b/include/linux/poison.h index 0d105a56e668..603d3bda31d9 100644 --- a/include/linux/poison.h +++ b/include/linux/poison.h @@ -1,13 +1,19 @@ #ifndef _LINUX_POISON_H #define _LINUX_POISON_H +/********** include/linux/list.h **********/ + +/* + * Architectures might want to move the poison pointer offset + * into some well-recognized area such as 0xdead000000000000, + * that is also not mappable by user-space exploits: + */ #ifdef CONFIG_ILLEGAL_POINTER_VALUE -#define POISON_POINTER_DELTA CONFIG_ILLEGAL_POINTER_VALUE +# define POISON_POINTER_DELTA CONFIG_ILLEGAL_POINTER_VALUE #else -#define POISON_POINTER_DELTA 0L +# define POISON_POINTER_DELTA 0 #endif -/********** include/linux/list.h **********/ /* * These are non-NULL pointers that will result in page faults * under normal circumstances, used to verify that nobody uses -- cgit v1.2.3 From 36b21230589ee51763afcc9ba2d126973f3ae96c Mon Sep 17 00:00:00 2001 From: Jaswinder Singh Rajput Date: Sat, 27 Dec 2008 15:21:36 +0530 Subject: x86: eliminate atleast 10684 sparse warnings Impact: cleanup, avoid 10000+ sparse warnings Eliminate 1434 sparse warnings like: include/linux/list.h:106:16: warning: constant 0xdead000000000000 is so big it is unsigned long Eliminate 1434 sparse warnings like: include/linux/list.h:107:16: warning: constant 0xdead000000000000 is so big it is unsigned long Eliminate 1434 sparse warnings like: include/linux/list.h:579:12: warning: constant 0xdead000000000000 is so big it is unsigned long Eliminate 1434 sparse warnings like: include/linux/list.h:580:13: warning: constant 0xdead000000000000 is so big it is unsigned long Eliminate 1237 sparse warnings like: include/linux/rculist.h:97:16: warning: constant 0xdead000000000000 is so big it is unsigned long Eliminate 1237 sparse warnings like: include/linux/rculist.h:143:14: warning: constant 0xdead000000000000 is so big it is unsigned long Eliminate 1237 sparse warnings like: include/linux/rculist.h:260:13: warning: constant 0xdead000000000000 is so big it is unsigned long Eliminate 1237 sparse warnings like: include/linux/rculist.h:280:15: warning: constant 0xdead000000000000 is so big it is unsigned long Signed-off-by: Jaswinder Singh Rajput Signed-off-by: Ingo Molnar --- include/linux/poison.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/poison.h b/include/linux/poison.h index 603d3bda31d9..f2de9a999f4a 100644 --- a/include/linux/poison.h +++ b/include/linux/poison.h @@ -9,7 +9,7 @@ * that is also not mappable by user-space exploits: */ #ifdef CONFIG_ILLEGAL_POINTER_VALUE -# define POISON_POINTER_DELTA CONFIG_ILLEGAL_POINTER_VALUE +# define POISON_POINTER_DELTA _AC(CONFIG_ILLEGAL_POINTER_VALUE, UL) #else # define POISON_POINTER_DELTA 0 #endif -- cgit v1.2.3