• Roland McGrath's avatar
    In fs/binfmt_elf.c, load_elf_interp() calls padzero() for .bss even if the · 2e1a32d9
    Roland McGrath authored
    PT_LOAD has no PROT_WRITE and no .bss.  This generates EFAULT.
    
    Here is a small test case.  (Yes, there are other, useful PT_INTERP which
    have only .text and no .data/.bss.)
    
    	----- ptinterp.S
    	_start: .globl _start
    		 nop
    		 int3
    	-----
    	$ gcc -m32 -nostartfiles -nostdlib -o ptinterp ptinterp.S
    	$ gcc -m32 -Wl,--dynamic-linker=ptinterp -o hello hello.c
    	$ ./hello
    	Segmentation fault  # during execve() itself
    
    	After applying the patch:
    	$ ./hello
    	Trace trap  # user-mode execution after execve() finishes
    
    If the ELF headers are actually self-inconsistent, then dying is fine. 
    But having no PROT_WRITE segment is perfectly normal and correct if there
    is no segment with p_memsz > p_filesz (i.e.  bss).  John Reiser suggested
    checking for PROT_WRITE in the bss logic.  I think it makes most sense to
    simply apply the bss logic only when there is bss.
    
    This patch looks less trivial than it is due to some reindentation.  It
    just moves the "if (last_bss > elf_bss) {" test up to include the
    partial-page bss logic as well as the more-pages bss logic.
    Reported-by: default avatarJohn Reiser <jreiser@bitwagon.com>
    Signed-off-by: default avatarRoland McGrath <roland@redhat.com>
    Cc: Alexander Viro <viro@zeniv.linux.org.uk>
    Cc: James Morris <jmorris@namei.org>
    Cc: David Howells <dhowells@redhat.com>
    Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
    2e1a32d9
binfmt_elf.c 53.8 KB