Bug 5411

Summary: kernel kills valid ELF binaries.
Product: Other Reporter: Pawel Sikora (pluto)
Component: OtherAssignee: other_other
Status: CLOSED CODE_FIX    
Severity: blocking CC: akpm
Priority: P2    
Hardware: i386   
OS: Linux   
Kernel Version: 2.6.14rc3-git6 Subsystem:
Regression: --- Bisected commit-id:

Description Pawel Sikora 2005-10-10 06:08:08 UTC
Software Environment: 
 
binutils-2.16.91.0.3 
 
Problem Description: 
 
The fs/binfmt_elf.c:load_elf_binary() always calls padzero() 
to fill the .bss section. If binary hasn't this section kernel 
will kill it immediately. 
 
(...) 
       if (padzero(elf_bss)) { 
           ^^^^^^^^^^^^^^^^ this method faults. 
                send_sig(SIGSEGV, current, 0); 
                retval = -EFAULT; /* Nobody gets to see this, but.. */ 
                goto out_free_dentry; 
(...) 
 
Steps to reproduce: 
 
$ cat xxx.S 
.section        .text 
.global         _start 
_start: 
        movl    $1, %eax 
        movl    $0, %ebx 
        int     $0x80 
.end 
 
$ as xxx.S -o xxx.o; ld xxx.o -o xxx -s; objdump -x xxx 
 
The output contains only .text section: 
 
Sections: 
Idx Name          Size      VMA       LMA       File off  Algn 
  0 .text         0000000c  08048094  08048094  00000094  2**2 
                  CONTENTS, ALLOC, LOAD, READONLY, CODE 
 
$ strace ./xxx 
execve("./xxx", ["./xxx"], [/* 37 vars */]) = -1 EFAULT (Bad address) 
--- SIGSEGV (Segmentation fault) @ 0 (0) --- 
+++ killed by SIGSEGV +++ 
 
Binaries with .bss or .data section are loaded without any errors. 
This bug blocks development of microapplications based on klibc.
Comment 1 Andrew Morton 2005-10-10 21:12:03 UTC
Please try binfmt_elf-bss-padding-fix.patch from -mm kernels.

I've been sitting on that patch for ages - I haven't really
seen a need to push it.  Please convince me ;)
Comment 2 Pawel Sikora 2005-10-11 04:28:21 UTC
> Please try binfmt_elf-bss-padding-fix.patch from -mm kernels. 
 
Heh, the patch from -mm kernel looks similar to mine :)  
http://cvs.pld-linux.org/cgi-bin/cvsweb/SOURCES/kernel-hotfixes.patch?r1=1.1.2.62&r2=1.1.2.63  
 
> I've been sitting on that patch for ages - I haven't really 
> seen a need to push it.  Please convince me ;) 
 
1). Many of klibc-based early-userspace are minimalistic 
    (w/o .bss | .data) and technically ok. 
2). Many of klibc-enabled packages use in ./configure tests 
    similar to `int main(){}` and kernel kills these tests. 
3). http://lkml.org/lkml/2005/10/8/42 
 
I don't see why I have to do workarounds for KERNEL BUG in all these places. 
The real fix takes a one line. Is it so hard to commit it? 
 
Comment 3 Pawel Sikora 2005-10-11 05:59:45 UTC
Hmm, I'm little confused now... 
 
Dick Johnson in reply to my post on lkml:([2.6] binfmt_elf bug ...) said: 
 
[cite] 
 
> [/me] 
> Please tell me what requires these useless zero-sized .data/.bss sections? 
> Kernel design or something else? (e.g. some standard?) 
 
[D.J.] 
Not kernel design. It's implimentation details for 'C' and its 
libraries. Any scratch buffers go into the .bss section, normally 
alocated and zeroed by the program loader in the kernel. To 
accommodate the 'C' design, the linker provides these sections 
even if the program wasn't created using 'C'. The 'rules' about 
where the .bss section is, how long it is, and what needs to 
be done with it, are "known" by the kernel. If the rules are 
not followed, the kernel should protect itself, but otherwise 
all bets are off -- you get zapped. 
 
> [/me] 
> I think kernel elf loader doesn't handle binaries without .bss. 
> Earlier binutils (<2.16) emits zero-sized .data/.bss and problem 
> wasn't exposed. Modern binutils doesn't emit useless zero-sized 
> .data/.bss sections and kernel kills these binaries. 
 
[D.J.] 
Well the "useless" zero-sized .bss section is not useless. It 
represents a rule that requires no resources, only compliance. 
The "fix" should not be in the kernel. Since the linker provides 
"fixups" as well as relocation, the linker should properly 
handle the .bss section as it has in the past. 
 
[/cite] 
 
So, finally I'll ask H.J.Lu about this issue... 
 
Comment 4 H.J. Lu 2005-10-11 07:34:07 UTC
Kernel doesn't see .bss section at all. It only sees segments. I don't see
how .bss section is required. If someone can show me that the ELF ABI
requires such a thing, I will fix linker.
Comment 5 Pawel Sikora 2005-10-24 14:08:57 UTC
commit 6de505173e24e76bb33a2595312e0c2b44d49e58 
Author: akpm@osdl.org <akpm@osdl.org> 
Date:   Tue Oct 11 08:29:08 2005 -0700 
 
    [PATCH] binfmt_elf bss padding fix 
     
    Nir Tzachar <tzachar@cs.bgu.ac.il> points out that if an ELF file 
    specifies a zero-length bss at a whacky address, we cannot load that 
    binary because padzero() tries to zero out the end of the page at the 
    whacky address, and that may not be writeable. 
    See also http://bugzilla.kernel.org/show_bug.cgi?id=5411 
    So teach load_elf_binary() to skip the bss settng altogether if the elf 
    file has a zero-length bss segment. 
     
    Cc: Roland McGrath <roland@redhat.com> 
    Cc: Daniel Jacobowitz <dan@debian.org> 
    Signed-off-by: Andrew Morton <akpm@osdl.org> 
    Signed-off-by: Linus Torvalds <torvalds@osdl.org>