Commit a29815a3 authored by Avi Kivity's avatar Avi Kivity Committed by Linus Torvalds

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
areas that cannot be mapped.

Other 64-bit architectures will likely find similar unmapped ranges.

[ingo: switch to 0xdead000000000000 as the unmapped area]
[ingo: add comments, cleanup]
[jaswinder: eliminate sparse warnings]
Acked-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: default avatarJaswinder Singh Rajput <jaswinderrajput@gmail.com>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarAvi Kivity <avi@redhat.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent c0f607c6
...@@ -1247,6 +1247,11 @@ config ARCH_MEMORY_PROBE ...@@ -1247,6 +1247,11 @@ config ARCH_MEMORY_PROBE
def_bool X86_64 def_bool X86_64
depends on MEMORY_HOTPLUG depends on MEMORY_HOTPLUG
config ILLEGAL_POINTER_VALUE
hex
default 0 if X86_32
default 0xdead000000000000 if X86_64
source "mm/Kconfig" source "mm/Kconfig"
config HIGHPTE config HIGHPTE
......
...@@ -2,13 +2,25 @@ ...@@ -2,13 +2,25 @@
#define _LINUX_POISON_H #define _LINUX_POISON_H
/********** include/linux/list.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 _AC(CONFIG_ILLEGAL_POINTER_VALUE, UL)
#else
# define POISON_POINTER_DELTA 0
#endif
/* /*
* These are non-NULL pointers that will result in page faults * These are non-NULL pointers that will result in page faults
* under normal circumstances, used to verify that nobody uses * under normal circumstances, used to verify that nobody uses
* non-initialized list entries. * non-initialized list entries.
*/ */
#define LIST_POISON1 ((void *) 0x00100100) #define LIST_POISON1 ((void *) 0x00100100 + POISON_POINTER_DELTA)
#define LIST_POISON2 ((void *) 0x00200200) #define LIST_POISON2 ((void *) 0x00200200 + POISON_POINTER_DELTA)
/********** include/linux/timer.h **********/ /********** include/linux/timer.h **********/
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment