• Andrew Morton's avatar
    [PATCH] fix ELF exec with huge bss · 0363994f
    Andrew Morton authored
    From: Roland McGrath <roland@redhat.com>
    
    The following test program will crash every time if dynamically linked.
    I think this bites all 32-bit platforms, including 32-bit executables on
    64-bit platforms that support them (and could in theory bite 64-bit
    platforms with bss sizes beyond the bounds of comprehension).
    
    	volatile char hugebss[1080000000];
    	main() { printf("%p..%p\n", &hugebss[0], &hugebss[sizeof hugebss]);
    	 system("cat /proc/$PPID/maps");
    	 hugebss[sizeof hugebss - 1] = 1;
    	 return 23;
    	}
    
    The problem is that the kernel maps ld.so at 0x40000000 or some such place,
    before it maps the bss.  Here the bss is so large that it overlaps and
    clobbers that mapping.  I've changed it to map the bss before it loads the
    interpreter, so that part of the address space is reserved before ld.so's
    mapping (which doesn't really care where it goes) is done.
    
    This patch also adds error checking to the bss setup (and interpreter's bss
    setup).  With the aforementioned change but no error checking, "ulimit -v
    65536; ./hugebss" will crash in the store after the `system' call, because
    the kernel will have failed to allocate the bss and ignored the error, so
    the program runs without those pages being mapped at all.  With this change
    it dies with a SIGKILL as for a failure to set up stack pages.  It might be
    even better to try to detect the case earlier so that execve can return an
    error before it has wiped out the address space.  But that seems like it
    would always be fragile and miss some corner cases, so I did not try to add
    such complexity.
    0363994f
binfmt_elf.c 40.2 KB