Andrew, the following two patches are the outcome of the thread "brk randomization breaks columns" [1]. As brk randomization is already in Linus' tree, it's definitely 2.6.25 material, so it would probably be good if you could push them in your next bunch going to Linus, if noone has any objections. I think it's better if they go through you than through Ingo, as they are not x86-specific at all. Thanks. [1] http://lkml.org/lkml/2008/2/4/83 -- Jiri Kosina SUSE Labs --
From: Jiri Kosina <jkosina@suse.cz> brk: check the lower bound properly There is a check in sys_brk(), that tries to make sure that we do not underflow the area that is dedicated to brk heap. The check is however wrong, as it assumes that brk area starts immediately after the end of the code (+bss), which is wrong for example in environments with randomized brk start. The proper way is to check whether the address is not below the start_brk address. Cc: Ingo Molnar <mingo@elte.hu> Cc: Arjan van de Ven <arjan@infradead.org> Acked-by: Hugh Dickins <hugh@veritas.com> Acked-by: Pavel Machek <pavel@suse.cz> Signed-off-by: Jiri Kosina <jkosina@suse.cz> diff --git a/mm/mmap.c b/mm/mmap.c index 8295577..1c3b48f 100644 --- a/mm/mmap.c +++ b/mm/mmap.c @@ -241,7 +241,7 @@ asmlinkage unsigned long sys_brk(unsigned long brk) down_write(&mm->mmap_sem); - if (brk < mm->end_code) + if (brk < mm->start_brk) goto out; /* --
From: Jiri Kosina <jkosina@suse.cz> ASLR: add possibility for more fine-grained tweaking Some prehistoric binaries don't like when start of brk area is located anywhere else than just after code+bss. This patch adds possibility to configure the default behavior of address space randomization. In addition to that, randomize_va_space now can have value of '2', which means full randomization including brk space. Also, documentation of randomize_va_space is added. Cc: Ingo Molnar <mingo@elte.hu> Cc: Arjan van de Ven <arjan@infradead.org> Cc: Randy Dunlap <randy.dunlap@oracle.com> Cc: Hugh Dickins <hugh@veritas.com> Cc: Pavel Machek <pavel@ucw.cz> Signed-off-by: Jiri Kosina <jkosina@suse.cz> diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index 8984a53..91ab40d 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -41,6 +41,7 @@ show up in /proc/sys/kernel: - pid_max - powersave-nap [ PPC only ] - printk +- randomize_va_space - real-root-dev ==> Documentation/initrd.txt - reboot-cmd [ SPARC only ] - rtsig-max @@ -280,6 +281,37 @@ send before ratelimiting kicks in. ============================================================== +randomize-va-space: + +This option can be used to select the type of process address +space randomization that is used in the system, for architectures +that support this feature. + +One of the following numeric values is possible: + +0 - [none] + Turn the process address space randomization off by default. + +1 - [conservative] + Conservative address space randomization makes the addresses of + mmap base and VDSO page randomized. This, among other things, + implies that shared libraries will be loaded to random addresses. + Also for PIE binaries, the location of code start is randomized. + +2 - [full] + + This includes all the features that Conservative randomization + provides. In addition to that, also start of ...
i've already added the patch below to x86.git. Ingo --------------------> Subject: brk randomization: introduce CONFIG_COMPAT_BRK From: Ingo Molnar <mingo@elte.hu> based on similar patch from: Pavel Machek <pavel@ucw.cz> Introduce CONFIG_COMPAT_BRK. If disabled then the kernel is free (but not obliged to) randomize the brk area. Heap randomization breaks ancient binaries, so we keep COMPAT_BRK enabled by default. Signed-off-by: Ingo Molnar <mingo@elte.hu> --- fs/binfmt_elf.c | 2 +- init/Kconfig | 12 ++++++++++++ mm/memory.c | 13 ++++++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) Index: linux-x86.q/fs/binfmt_elf.c =================================================================== --- linux-x86.q.orig/fs/binfmt_elf.c +++ linux-x86.q/fs/binfmt_elf.c @@ -1077,7 +1077,7 @@ static int load_elf_binary(struct linux_ current->mm->start_stack = bprm->p; #ifdef arch_randomize_brk - if (current->flags & PF_RANDOMIZE) + if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1)) current->mm->brk = current->mm->start_brk = arch_randomize_brk(current->mm); #endif Index: linux-x86.q/init/Kconfig =================================================================== --- linux-x86.q.orig/init/Kconfig +++ linux-x86.q/init/Kconfig @@ -541,6 +541,18 @@ config ELF_CORE help Enable support for generating core dumps. Disabling saves about 4k. +config COMPAT_BRK + bool "Disable heap randomization" + default y + help + Randomizing heap placement makes heap exploits harder, but it + also breaks ancient binaries (including anything libc5 based). + This option changes the bootup default to heap randomization + disabled, and can be overriden runtime by setting + /proc/sys/kernel/randomize_va_space to 2. + + On non-ancient distros (post-2000 ones) Y is usually a safe choice. + config BASE_FULL default y bool "Enable full-sized data structures for core" if EMBEDDED Index: ...
OK, cool, thanks. Still, I think that we want the Documentation/sysctl/kernel.txt part of my patch probably. Updated patch below. From: Jiri Kosina <jkosina@suse.cz> Document randomize_va_space and CONFIG_COMPAT_BRK diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt index 8984a53..dc8801d 100644 --- a/Documentation/sysctl/kernel.txt +++ b/Documentation/sysctl/kernel.txt @@ -41,6 +41,7 @@ show up in /proc/sys/kernel: - pid_max - powersave-nap [ PPC only ] - printk +- randomize_va_space - real-root-dev ==> Documentation/initrd.txt - reboot-cmd [ SPARC only ] - rtsig-max @@ -280,6 +281,34 @@ send before ratelimiting kicks in. ============================================================== +randomize-va-space: + +This option can be used to select the type of process address +space randomization that is used in the system, for architectures +that support this feature. + +0 - Turn the process address space randomization off by default. + +1 - Make the addresses of mmap base, stack and VDSO page randomized. + This, among other things, implies that shared libraries will be + loaded to random addresses. Also for PIE-linked binaries, the location + of code start is randomized. + + With heap randomization, the situation is a little bit more + complicated. + There a few legacy applications out there (such as some ancient + versions of libc.so.5 from 1996) that assume that brk area starts + just after the end of the code+bss. These applications break when + start of the brk area is randomized. There are however no known + non-legacy applications that would be broken this way, so for most + systems it is safe to choose full randomization. However there is + a CONFIG_COMPAT_BRK option for systems with ancient and/or broken + binaries, that makes heap non-randomized, but keeps all other + parts of process address space randomized if ...
thanks, applied. i'm wondering about the following detail: i guess on 64-bit x86 kernels we could default to !CONFIG_COMPAT_BRK? In 1997 there was no 64-bit x86. Maybe for compat 32-bit binaries we could keep it off, but always do it for 64-bit binaries. Ingo --
.. and I have just noticed that my patch was by mistake missing signoff. Could you please add Signed-off-by: Jiri Kosina <jkosina@suse.cz> That actually makes sense, thanks. I will send you a patch. Thanks, -- Jiri Kosina SUSE Labs --
So what do you think is proper behavior in situation when CONFIG_COMPAT_BRK=N on 64bit kernel, and 32bit-binary is loaded in 32bit emulation? We can either leave the brk as-is, but that is in contradiction to user explictly specifying CONFIG_COMPAT_BRK=N. Is this what you propose? Or we can randomize brk start in such situation, but that is the behavior we currently automatically have due to CONFIG_COMPAT_BRK=N, so no change is needed. Thanks, -- Jiri Kosina SUSE Labs --
thinking about it ... i think we should just keep this simple, and when COMPAT_BRK=y then we disable brk randomization globally. If !COMPAT_BRK then we do brk randomization globally as well. (and that is probably what users want the sysctl to do anyway - users wont necessarily know whether the app breakage they want to solve is due to 32-bit or 64-bit.) Ingo --
Somehow my belly feeling tells me something is wrong with this description... Ah, a negative option (Y -> disable). So Y is always safe. `non-ancient distros' really means `recent distros', and if you have one, then _N_ should be a safe choice, too? With kind regards, Geert Uytterhoeven Software Architect Sony Network and Software Technology Center Europe The Corporate Village
This indeed looks wrong. The default should be N and the text should say "On recent distros (post-2000 ones) N is usually a safe choice". Regards, ismail -- Never learn by your mistakes, if you do you may never dare to try again. --
yeah, you are right :-) I'll fix this. btw., "non-ancient distros" does not just mean "recent distros", it really means "just about any distro you picked up in the past 10 years". You'd have to go out on a limb to find something historic (or keep copying /lib/libc5 binaries to new distros like Pavel did) to still have this particular libc5 assumption/breakage. [ Or at least so i hope =B-)] Ingo --
Bummer, I guess my good old m68k recovery ramdisk is affected ;-) With kind regards, Geert Uytterhoeven Software Architect Sony Network and Software Technology Center Europe The Corporate Village
