On Fri, Oct 31 2014, Junjie Mao wrote: > When choosing a random address, the current implementation does not take into > account the reversed space for .bss and .brk sections. Thus the relocated kernel > may overlap other components in memory. Here is an example of the overlap from a > x86_64 kernel in qemu (the ranges of physical addresses are presented): > > Physical Address > > 0x0fe00000 --+--------------------+ <-- randomized base > / | relocated kernel | > vmlinux.bin | (from vmlinux.bin) | > 0x1336d000 (an ELF file) +--------------------+-- > \ | | \ > 0x1376d870 --+--------------------+ | > | relocs table | | > 0x13c1c2a8 +--------------------+ .bss and .brk > | | | > 0x13ce6000 +--------------------+ | > | | / > 0x13f77000 | initrd |-- > | | > 0x13fef374 +--------------------+ > > The initrd image will then be overwritten by the memset during early > initialization: > > [ 1.655204] Unpacking initramfs... > [ 1.662831] Initramfs unpacking failed: junk in compressed archive > > This patch prevents the above situation by requiring a larger space when looking > for a random kernel base, so that existing logic can effectively avoids the > overlap. > > Fixes: 82fa9637a2 ("x86, kaslr: Select random position from e820 maps") > Reported-by: Fengguang Wu <fengguang.wu@xxxxxxxxx> > Signed-off-by: Junjie Mao <eternal.n08@xxxxxxxxx> > [kees: switched to perl to avoid hex translation pain in mawk vs gawk] > [kees: calculated overlap without relocs table] > Signed-off-by: Kees Cook <keescook@xxxxxxxxxxxx> > Cc: stable@xxxxxxxxxxxxxxx > --- > This version updates the commit log only. > > Kees, please help review the documentation. Thanks! > > Best Regards > Junjie Mao [...] > diff --git a/arch/x86/tools/calc_run_size.pl b/arch/x86/tools/calc_run_size.pl > new file mode 100644 > index 000000000000..0b0b124d3ece > --- /dev/null > +++ b/arch/x86/tools/calc_run_size.pl > @@ -0,0 +1,30 @@ > +#!/usr/bin/perl > +# > +# Calculate the amount of space needed to run the kernel, including room for > +# the .bss and .brk sections. > +# > +# Usage: > +# objdump -h a.out | perl calc_run_size.pl > +use strict; > + > +my $mem_size = 0; > +my $file_offset = 0; > + > +my $sections=" *[0-9]+ \.(?:bss|brk) +"; > +while (<>) { > + if (/^$sections([0-9a-f]+) +(?:[0-9a-f]+ +){2}([0-9a-f]+)/) { > + my $size = hex($1); > + my $offset = hex($2); > + $mem_size += $size; > + if ($file_offset == 0) { > + $file_offset = $offset; > + } elsif ($file_offset != $offset) { > + die ".bss and .brk lack common file offset\n"; > + } > + } > +} > + > +if ($file_offset == 0) { > + die "Never found .bss or .brk file offset\n"; > +} > +printf("%d\n", $mem_size + $file_offset); Given that bss and brk are nobits (i.e. only ALLOC) sections, does file_offset make sense as a load address. This fails with gold: $ git checkout v3.18-rc5 $ make # with gold [...] ..bss and .brk lack common file offset ..bss and .brk lack common file offset ..bss and .brk lack common file offset ..bss and .brk lack common file offset MKPIGGY arch/x86/boot/compressed/piggy.S Usage: arch/x86/boot/compressed/mkpiggy compressed_file run_size make[2]: *** [arch/x86/boot/compressed/piggy.S] Error 1 make[1]: *** [arch/x86/boot/compressed/vmlinux] Error 2 make: *** [bzImage] Error 2 In ld.bfd brk/bss file_offsets match, but they differ with ld.gold: $ objdump -h vmlinux.ld [...] 0 .text 00818bb3 ffffffff81000000 0000000001000000 00200000 2**12 CONTENTS, ALLOC, LOAD, READONLY, CODE [...] 26 .bss 000e0000 ffffffff81fe8000 0000000001fe8000 013e8000 2**12 ALLOC 27 .brk 00026000 ffffffff820c8000 00000000020c8000 013e8000 2**0 ALLOC $ objdump -h vmlinux.ld | perl arch/x86/tools/calc_run_size.pl 21946368 # aka 0x14ee000 $ objdump -h vmlinux.gold [...] 0 .text 00818bb3 ffffffff81000000 0000000001000000 00001000 2**12 CONTENTS, ALLOC, LOAD, READONLY, CODE [...] 26 .bss 000e0000 ffffffff81feb000 0000000001feb000 00e90000 2**12 ALLOC 27 .brk 00026000 ffffffff820cb000 00000000020cb000 00f70000 2**0 ALLOC -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html