2005-10-07 10:09:14

by Paweł Sikora

[permalink] [raw]
Subject: [2.6] binfmt_elf bug (exposed by klibc).

Hi All,

I've a simple program called empty.c.

$ cat empty.c

int main(int argc, char* argv[])
{
return 0;
}

$ cat empty410.s

.file "empty.c"
.text
.p2align 4,,15
.globl main
.type main, @function
main:
xorl %eax, %eax
ret
.size main, .-main
.ident "GCC: (GNU) 4.1.0 20050922 (experimental)"
.section .note.GNU-stack,"", at progbits

binutils-2.15.94.0.2.2 produces for this code empty .data and .bss sections:

Program Header:
PHDR off 0x00000034 vaddr 0x08048034 paddr 0x08048034 align 2**2
filesz 0x000000c0 memsz 0x000000c0 flags r-x
INTERP off 0x000000f4 vaddr 0x080480f4 paddr 0x080480f4 align 2**0
filesz 0x0000002a memsz 0x0000002a flags r--
LOAD off 0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12
filesz 0x00000123 memsz 0x00000123 flags r-x
LOAD off 0x00000124 vaddr 0x08049124 paddr 0x08049124 align 2**12
filesz 0x00000000 memsz 0x00000000 flags rw-
STACK off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
filesz 0x00000000 memsz 0x00000000 flags rwx
PAX_FLAGS off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
filesz 0x00000000 memsz 0x00000000 flags --- 2800

Sections:
Idx Name Size VMA LMA File off Algn
0 .interp 0000002a 080480f4 080480f4 000000f4 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .text 00000003 08048120 08048120 00000120 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .data 00000000 08049124 08049124 00000124 2**2
CONTENTS, ALLOC, LOAD, DATA
3 .bss 00000000 08049124 08049124 00000124 2**2
ALLOC

and /lib/klibc-*.so interpeter works fine.

binutils-2.16.91.0.3 doesn't produce useless empty sections:

Program Header:
PHDR off 0x00000034 vaddr 0x08048034 paddr 0x08048034 align 2**2
filesz 0x000000a0 memsz 0x000000a0 flags r-x
INTERP off 0x000000f4 vaddr 0x080480f4 paddr 0x080480f4 align 2**0
filesz 0x0000002a memsz 0x0000002a flags r--
LOAD off 0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12
filesz 0x00000123 memsz 0x00000123 flags r-x
STACK off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
filesz 0x00000000 memsz 0x00000000 flags rwx
PAX_FLAGS off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
filesz 0x00000000 memsz 0x00000000 flags --- 2800

Sections:
Idx Name Size VMA LMA File off Algn
0 .interp 0000002a 080480f4 080480f4 000000f4 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .text 00000003 08048120 08048120 00000120 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE

...and klibc's loader doesn't reach crt0.o:_start().

It receives sigsegv from kernel. The load_elf_binary() calls
padzero() for nonexistent .bss mapping.

Attached workaround fixes problem. Could anybody look into this?

Regards,
Paweł.

--
The only thing necessary for the triumph of evil
is for good men to do nothing.
- Edmund Burke


Attachments:
(No filename) (3.18 kB)
linux-2.6-binfmt-empty-bss.patch (433.00 B)
testcase.tar.bz2 (12.22 kB)
Download all attachments

2005-10-07 13:46:12

by Horst H. von Brand

[permalink] [raw]
Subject: Re: [2.6] binfmt_elf bug (exposed by klibc).

Paweł Sikora <[email protected]> wrote:
> I've a simple program called empty.c.
>
> $ cat empty.c
>
> int main(int argc, char* argv[])
> {
> return 0;
> }
>
> $ cat empty410.s
>
> .file "empty.c"
> .text
> .p2align 4,,15
> .globl main
> .type main, @function
> main:
> xorl %eax, %eax
> ret
> .size main, .-main
> .ident "GCC: (GNU) 4.1.0 20050922 (experimental)"
> .section .note.GNU-stack,"", at progbits

I get a substantially different empty.s (gcc-4.0.2, Fedora rawhide on i686):

.file "empty.c"
.text
.p2align 2,,3
.globl main
.type main, @function
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
subl $16, %esp
xorl %eax, %eax
leave
ret
.size main, .-main
.ident "GCC: (GNU) 4.0.2 20050928 (Red Hat 4.0.2-1)"
.section .note.GNU-stack,"",@progbits

> binutils-2.15.94.0.2.2 produces for this code empty .data and .bss
> sections:

binutils-2.16.91.0.2-4 doesn't. It looks like you are using broken tools.
--
Dr. Horst H. von Brand User #22616 counter.li.org
Departamento de Informatica Fono: +56 32 654431
Universidad Tecnica Federico Santa Maria +56 32 654239
Casilla 110-V, Valparaiso, Chile Fax: +56 32 797513

2005-10-07 14:11:38

by linux-os (Dick Johnson)

[permalink] [raw]
Subject: Re: [2.6] binfmt_elf bug (exposed by klibc).


On Fri, 7 Oct 2005, Horst von Brand wrote:

> Pawe?' Sikora <[email protected]> wrote:
>> I've a simple program called empty.c.
>>
>> $ cat empty.c
>>
>> int main(int argc, char* argv[])
>> {
>> return 0;
>> }
>>
>> $ cat empty410.s
>>
>> .file "empty.c"
>> .text
>> .p2align 4,,15
>> .globl main
>> .type main, @function
>> main:
>> xorl %eax, %eax
>> ret
>> .size main, .-main
>> .ident "GCC: (GNU) 4.1.0 20050922 (experimental)"
>> .section .note.GNU-stack,"", at progbits
>

With this compilation, the 'C' compiler looked and said; "you
are just going to return 0..." So that's the code it generated.
This compiler probably defaults to "-fomit-frame-pointer".


> I get a substantially different empty.s (gcc-4.0.2, Fedora rawhide on i686):
>
> .file "empty.c"
> .text
> .p2align 2,,3
> .globl main
> .type main, @function
> main:
> pushl %ebp
> movl %esp, %ebp
> subl $8, %esp
> andl $-16, %esp
> subl $16, %esp
> xorl %eax, %eax
> leave
> ret
> .size main, .-main
> .ident "GCC: (GNU) 4.0.2 20050928 (Red Hat 4.0.2-1)"
> .section .note.GNU-stack,"",@progbits


With this compiler, it assumed that you were going to do something
useful so it set up a stack-frame. It also aligned the stack after
it saved the intitial value in EBP. Then it cleared the return-
value, reset the stack, and returned.

This compiler did not default to "-fomit-frame-pointer" so it
set up a stack-frame.

>
>> binutils-2.15.94.0.2.2 produces for this code empty .data and .bss
>> sections:
>

There is nothing wrong here at all.

> binutils-2.16.91.0.2-4 doesn't. It looks like you are using broken tools.
> --
> Dr. Horst H. von Brand User #22616 counter.li.org
> Departamento de Informatica Fono: +56 32 654431
> Universidad Tecnica Federico Santa Maria +56 32 654239
> Casilla 110-V, Valparaiso, Chile Fax: +56 32 797513
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>

Cheers,
Dick Johnson
Penguin : Linux version 2.6.13 on an i686 machine (5589.54 BogoMips).
Warning : 98.36% of all statistics are fiction.

****************************************************************
The information transmitted in this message is confidential and may be privileged. Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited. If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to [email protected] - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

2005-10-07 14:21:49

by Paweł Sikora

[permalink] [raw]
Subject: Re: [2.6] binfmt_elf bug (exposed by klibc).

Dnia piątek, 7 października 2005 15:46, Horst von Brand napisał:
> Paweł Sikora <[email protected]> wrote:
> > I've a simple program called empty.c.
> >
> > $ cat empty.c
> >
> > int main(int argc, char* argv[])
> > {
> > return 0;
> > }
> >
> > $ cat empty410.s
> >
> > .file "empty.c"
> > .text
> > .p2align 4,,15
> > .globl main
> > .type main, @function
> > main:
> > xorl %eax, %eax
> > ret
> > .size main, .-main
> > .ident "GCC: (GNU) 4.1.0 20050922 (experimental)"
> > .section .note.GNU-stack,"", at progbits
>
> I get a substantially different empty.s (gcc-4.0.2, Fedora rawhide on
> i686):
>
> .file "empty.c"
> .text
> .p2align 2,,3
> .globl main
> .type main, @function
> main:
> pushl %ebp
> movl %esp, %ebp
> subl $8, %esp
> andl $-16, %esp
> subl $16, %esp
> xorl %eax, %eax
> leave
> ret
> .size main, .-main
> .ident "GCC: (GNU) 4.0.2 20050928 (Red Hat 4.0.2-1)"
> .section .note.GNU-stack,"",@progbits
>
> > binutils-2.15.94.0.2.2 produces for this code empty .data and .bss
> > sections:
>
> binutils-2.16.91.0.2-4 doesn't. It looks like you are using broken tools.

I didn't say that is (or not) a binutils bug.
I'm only saying that kernel is killng a valid micro application.

--
The only thing necessary for the triumph of evil
is for good men to do nothing.
- Edmund Burke

2005-10-07 15:33:16

by Horst H. von Brand

[permalink] [raw]
Subject: Re: [2.6] binfmt_elf bug (exposed by klibc).

Paweł Sikora <[email protected]> wrote:
> Dnia piątek, 7 października 2005 15:46, Horst von Brand napisał:

[...]

> > binutils-2.16.91.0.2-4 doesn't. It looks like you are using broken tools.

> I didn't say that is (or not) a binutils bug.
> I'm only saying that kernel is killng a valid micro application.

If binutils generates an invalid executable, it is not a valid application.
--
Dr. Horst H. von Brand User #22616 counter.li.org
Departamento de Informatica Fono: +56 32 654431
Universidad Tecnica Federico Santa Maria +56 32 654239
Casilla 110-V, Valparaiso, Chile Fax: +56 32 797513

2005-10-07 15:41:47

by Paweł Sikora

[permalink] [raw]
Subject: Re: [2.6] binfmt_elf bug (exposed by klibc).

Dnia piątek, 7 października 2005 17:33, Horst von Brand napisał:
> Paweł Sikora <[email protected]> wrote:
> > Dnia piątek, 7 października 2005 15:46, Horst von Brand napisał:
>
> [...]
>
> > > binutils-2.16.91.0.2-4 doesn't. It looks like you are using broken
> > > tools.
> >
> > I didn't say that is (or not) a binutils bug.
> > I'm only saying that kernel is killng a valid micro application.
>
> If binutils generates an invalid executable, it is not a valid application.

ehh, please look again at my first post :)
binutils-2.16 generates VALID app with .text/.interp and *without* .bss.
kernel always calls padzero() for the .bss section inside load_elf_binary().
finally it kills a valid app. did i miss something?

--
The only thing necessary for the triumph of evil
is for good men to do nothing.
- Edmund Burke

2005-10-07 21:20:26

by Paweł Sikora

[permalink] [raw]
Subject: Re: [2.6] binfmt_elf bug (exposed by klibc).

Dnia piątek, 7 października 2005 18:16, linux-os (Dick Johnson) napisał:
> On Fri, 7 Oct 2005, [UTF-8] Pawe? Sikora wrote:
> > Dnia pitek, 7 padziernika 2005 17:33, Horst von Brand napisa:
> >> Pawe Sikora <[email protected]> wrote:
> >>> Dnia pitek, 7 padziernika 2005 15:46, Horst von Brand napisa:
> >>
> >> [...]
> >>
> >>>> binutils-2.16.91.0.2-4 doesn't. It looks like you are using broken
> >>>> tools.
> >>>
> >>> I didn't say that is (or not) a binutils bug.
> >>> I'm only saying that kernel is killng a valid micro application.
> >>
> >> If binutils generates an invalid executable, it is not a valid
> >> application.
> >
> > ehh, please look again at my first post :)
> > binutils-2.16 generates VALID app with .text/.interp and *without* .bss.
> > kernel always calls padzero() for the .bss section inside
> > load_elf_binary(). finally it kills a valid app. did i miss something?
> >
>
> The executable created by this:
>
> $ cat <<EOF >xxx.S
> .section .rodata
> hello: .string "Hello World!\n"
> STRLEN = .-hello
> WRITE=4
> EXIT=1
>
> .section .text
> .global _start
> .type _start,@function
> _start:
> movl $WRITE, %eax
> movl $1, %ebx
> movl $hello, %ecx
> movl $STRLEN, %edx
> int $0x80
> movl $EXIT, %eax
> movl $0, %ebx
> int $0x80
> .end
> EOF
>
> $ as -o xxx.o xxx.S
> $ ld -o xxx xxx.o
> $ ./xxx
> Hello World!
> $
>
> ... does not have a .bss section. It also runs fine. The linker
> creates a 0 length .bss section starting at label "_end". There
> is no way to prevent it from happening so the kernel's zeroing
> the zero-length section is perfectly valid. Maybe you have
> executed `strip` and stripped out that section? If so, you
> no longer have a valid executable and the kernel should kill
> it.

What????????????
Do you suggest that stripped executables are invalid?

$ cat xxx.S
.section .text
.global _start
.type _start,@function
_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

xxx: file format elf32-i386
xxx
architecture: i386, flags 0x00000102:
EXEC_P, D_PAGED
start address 0x08048094

Program Header:
LOAD off 0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12
filesz 0x000000a0 memsz 0x000000a0 flags r-x
PAX_FLAGS off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
filesz 0x00000000 memsz 0x00000000 flags --- 2800

Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000000c 08048094 08048094 00000094 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE

We have a pure executable, no .data/.rodata/.bss/etc.

On 2.6.14rc3-git6 this executable doesn't work:

$ strace ./xxx
execve("./xxx", ["./xxx"], [/* 24 vars */]) = -1 EFAULT (Bad address)
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++

With hacked kernel it works pretty fine:

$ strace ./xxx
execve("./xxx", ["./xxx"], [/* 24 vars */]) = 0
_exit(0)

--
The only thing necessary for the triumph of evil
is for good men to do nothing.
- Edmund Burke

2005-10-07 22:43:08

by Paweł Sikora

[permalink] [raw]
Subject: Re: [2.6] binfmt_elf bug (exposed by klibc).

Dnia piątek, 7 października 2005 23:47, linux-os (Dick Johnson) napisał:
> On Fri, 7 Oct 2005, [UTF-8] Pawe? Sikora wrote:
> > Dnia pitek, 7 padziernika 2005 18:16, linux-os (Dick Johnson) napisa:
> >> On Fri, 7 Oct 2005, [UTF-8] Pawe? Sikora wrote:
> >>> Dnia pitek, 7 padziernika 2005 17:33, Horst von Brand napisa:
> >>>> Pawe Sikora <[email protected]> wrote:
> >>>>> Dnia pitek, 7 padziernika 2005 15:46, Horst von Brand napisa:
> >>>>
> >>>> [...]
> >>>>
> >>>>>> binutils-2.16.91.0.2-4 doesn't. It looks like you are using broken
> >>>>>> tools.
> >>>>>
> >>>>> I didn't say that is (or not) a binutils bug.
> >>>>> I'm only saying that kernel is killng a valid micro application.
> >>>>
> >>>> If binutils generates an invalid executable, it is not a valid
> >>>> application.
> >>>
> >>> ehh, please look again at my first post :)
> >>> binutils-2.16 generates VALID app with .text/.interp and *without*
> >>> .bss. kernel always calls padzero() for the .bss section inside
> >>> load_elf_binary(). finally it kills a valid app. did i miss something?
> >>
> >> The executable created by this:
> >>
> >> $ cat <<EOF >xxx.S
> >> .section .rodata
> >> hello: .string "Hello World!\n"
> >> STRLEN = .-hello
> >> WRITE=4
> >> EXIT=1
> >>
> >> .section .text
> >> .global _start
> >> .type _start,@function
> >> _start:
> >> movl $WRITE, %eax
> >> movl $1, %ebx
> >> movl $hello, %ecx
> >> movl $STRLEN, %edx
> >> int $0x80
> >> movl $EXIT, %eax
> >> movl $0, %ebx
> >> int $0x80
> >> .end
> >> EOF
> >>
> >> $ as -o xxx.o xxx.S
> >> $ ld -o xxx xxx.o
> >> $ ./xxx
> >> Hello World!
> >> $
> >>
> >> ... does not have a .bss section. It also runs fine. The linker
> >> creates a 0 length .bss section starting at label "_end". There
> >> is no way to prevent it from happening so the kernel's zeroing
> >> the zero-length section is perfectly valid. Maybe you have
> >> executed `strip` and stripped out that section? If so, you
> >> no longer have a valid executable and the kernel should kill
> >> it.
> >
> > What????????????
> > Do you suggest that stripped executables are invalid?
>
> No, not if you don't strip out sections that are required.

Please tell me what requires these useless zero-sized .data/.bss sections?
Kernel design or something else? (e.g. some standard?)
Maybe H.J.Lu will know better as we are.

> > $ cat xxx.S
> > .section .text
> > .global _start
> > .type _start,@function
> > _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
> >
> > xxx: file format elf32-i386
> > xxx
> > architecture: i386, flags 0x00000102:
> > EXEC_P, D_PAGED
> > start address 0x08048094
> >
> > Program Header:
> > LOAD off 0x00000000 vaddr 0x08048000 paddr 0x08048000 align 2**12
> > filesz 0x000000a0 memsz 0x000000a0 flags r-x
> > PAX_FLAGS off 0x00000000 vaddr 0x00000000 paddr 0x00000000 align 2**2
> > filesz 0x00000000 memsz 0x00000000 flags --- 2800
> >
> > Sections:
> > Idx Name Size VMA LMA File off Algn
> > 0 .text 0000000c 08048094 08048094 00000094 2**2
> > CONTENTS, ALLOC, LOAD, READONLY, CODE
> >
> > We have a pure executable, no .data/.rodata/.bss/etc.
>
> Your executable works fine on 2.6.14 as it should.

Hmm, it's strange. On my 2.6.14rc3-git6 + binutils-2.16.91.0.3
it doesn't work (vide -EFAULT). On 2.6.13 + binutils-2.15.94.0.2.2
it works fine (executable contains zero-sized .data + .bss sections).
(btw. fs/binfmt_elf.c are the same)

> > $ strace ./xxx
> > execve("./xxx", ["./xxx"], [/* 24 vars */]) = -1 EFAULT (Bad address)
> > --- SIGSEGV (Segmentation fault) @ 0 (0) ---
> > +++ killed by SIGSEGV +++
> >
> > With hacked kernel it works pretty fine:
>
> What did you hack? Patch please.

Ugly workaround: lkml.org/lkml/2005/10/7/48/

> Did somebody accidentally
> screw up some kernel code between 2.6.13 and 2.6.14?

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.

Regards,
Paweł.

--
The only thing necessary for the triumph of evil
is for good men to do nothing.
- Edmund Burke

2005-10-08 14:30:17

by Jan-Benedict Glaw

[permalink] [raw]
Subject: Re: [2.6] binfmt_elf bug (exposed by klibc).

On Sat, 2005-10-08 00:42:58 +0200, Paweł Sikora <[email protected]> wrote:
> > Did somebody accidentally
> > screw up some kernel code between 2.6.13 and 2.6.14?
>
> 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.

I had this problem at some time, too. This was when I started to redo
the uClibc port to vax-linux, which I started with a hand-crafted
assembly file. It also crashed upon execution, though I was sure the
program was technically okay.

However, I haven't looked up any paper or standard to verify either
position. So I don't know for *sure* if it's legal to omit these
(empty) sections.

MfG, JBG

--
Jan-Benedict Glaw [email protected] . +49-172-7608481 _ O _
"Eine Freie Meinung in einem Freien Kopf | Gegen Zensur | Gegen Krieg _ _ O
für einen Freien Staat voll Freier Bürger" | im Internet! | im Irak! O O O
ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA));


Attachments:
(No filename) (1.12 kB)
signature.asc (189.00 B)
Digital signature
Download all attachments

2005-10-08 19:29:22

by Paweł Sikora

[permalink] [raw]
Subject: Re: [2.6] binfmt_elf bug (exposed by klibc).

Dnia sobota, 8 października 2005 16:30, Jan-Benedict Glaw napisał:
> On Sat, 2005-10-08 00:42:58 +0200, Paweł Sikora <[email protected]> wrote:
> > > Did somebody accidentally
> > > screw up some kernel code between 2.6.13 and 2.6.14?
> >
> > 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.
>
> I had this problem at some time, too. This was when I started to redo
> the uClibc port to vax-linux, which I started with a hand-crafted
> assembly file. It also crashed upon execution, though I was sure the
> program was technically okay.

I think kernel wrongly assumes that all binaries in the world have
.text and at least .data/.bss. E.g. in embedded world software are
often pure, minimalistic and technically okay.

--
The only thing necessary for the triumph of evil
is for good men to do nothing.
- Edmund Burke