Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

brk: COMPAT_BRK: fix detection of randomized brk

5520e89 ("brk: fix min_brk lower bound computation for COMPAT_BRK")
tried to get the whole logic of brk randomization for legacy
(libc5-based) applications finally right.

It turns out that the way to detect whether brk has actually been
randomized in the end or not introduced by that patch still doesn't work
for those binaries, as reported by Geert:

: /sbin/init from my old m68k ramdisk exists prematurely.
:
: Before the patch:
:
: | brk(0x80005c8e) = 0x80006000
:
: After the patch:
:
: | brk(0x80005c8e) = 0x80005c8e
:
: Old libc5 considers brk() to have failed if the return value is not
: identical to the requested value.

I don't like it, but currently see no better option than a bit flag in
task_struct to catch the CONFIG_COMPAT_BRK && randomize_va_space == 2
case.

Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Tested-by: Geert Uytterhoeven <geert@linux-m68k.org>
Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Jiri Kosina and committed by
Linus Torvalds
4471a675 5de1743e

+9 -2
+5 -1
fs/binfmt_elf.c
··· 941 941 current->mm->start_stack = bprm->p; 942 942 943 943 #ifdef arch_randomize_brk 944 - if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1)) 944 + if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1)) { 945 945 current->mm->brk = current->mm->start_brk = 946 946 arch_randomize_brk(current->mm); 947 + #ifdef CONFIG_COMPAT_BRK 948 + current->brk_randomized = 1; 949 + #endif 950 + } 947 951 #endif 948 952 949 953 if (current->personality & MMAP_PAGE_ZERO) {
+3
include/linux/sched.h
··· 1254 1254 #endif 1255 1255 1256 1256 struct mm_struct *mm, *active_mm; 1257 + #ifdef CONFIG_COMPAT_BRK 1258 + unsigned brk_randomized:1; 1259 + #endif 1257 1260 #if defined(SPLIT_RSS_COUNTING) 1258 1261 struct task_rss_stat rss_stat; 1259 1262 #endif
+1 -1
mm/mmap.c
··· 259 259 * randomize_va_space to 2, which will still cause mm->start_brk 260 260 * to be arbitrarily shifted 261 261 */ 262 - if (mm->start_brk > PAGE_ALIGN(mm->end_data)) 262 + if (current->brk_randomized) 263 263 min_brk = mm->start_brk; 264 264 else 265 265 min_brk = mm->end_data;