Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Tue, 19 Jun 2012 23:17:33 +0200
From: Bruno Haible <bruno@...sp.org>
To: Rich Felker <dalias@...ifal.cx>
Cc: bug-gnulib@....org, musl@...ts.openwall.com
Subject: Re: musl, printf out-of-memory test

Rich Felker wrote:
> Do you have a dynamic-linked musl or just static?

Dynamically linked:

$ readelf -d conftest

Dynamic section at offset 0xf3c contains 18 entries:
  Tag        Type                         Name/Value
 0x00000001 (NEEDED)                     Shared library: [libc.so]
 0x0000000c (INIT)                       0x804832c
 0x0000000d (FINI)                       0x80484ec
 0x00000004 (HASH)                       0x80481a0
 0x6ffffef5 (GNU_HASH)                   0x80481dc
 0x00000005 (STRTAB)                     0x80482b0
 0x00000006 (SYMTAB)                     0x8048210
 0x0000000a (STRSZ)                      83 (bytes)
 0x0000000b (SYMENT)                     16 (bytes)
 0x00000015 (DEBUG)                      0x0
 0x00000003 (PLTGOT)                     0x8049ff4
 0x00000002 (PLTRELSZ)                   32 (bytes)
 0x00000014 (PLTREL)                     REL
 0x00000017 (JMPREL)                     0x804830c
 0x00000011 (REL)                        0x8048304
 0x00000012 (RELSZ)                      8 (bytes)
 0x00000013 (RELENT)                     8 (bytes)
 0x00000000 (NULL)                       0x0
$ readelf -l conftest

Elf file type is EXEC (Executable file)
Entry point 0x8048390
There are 9 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  PHDR           0x000034 0x08048034 0x08048034 0x00120 0x00120 R E 0x4
  INTERP         0x000154 0x08048154 0x08048154 0x00026 0x00026 R   0x1
      [Requesting program interpreter: /arch/x86-linux/inst-musl/lib/libc.so]
  LOAD           0x000000 0x08048000 0x08048000 0x00578 0x00578 R E 0x1000
  LOAD           0x000f28 0x08049f28 0x08049f28 0x000ec 0x000f8 RW  0x1000
  DYNAMIC        0x000f3c 0x08049f3c 0x08049f3c 0x000b8 0x000b8 RW  0x4
  NOTE           0x00017c 0x0804817c 0x0804817c 0x00024 0x00024 R   0x4
  GNU_EH_FRAME   0x000528 0x08048528 0x08048528 0x00014 0x00014 R   0x4
  GNU_STACK      0x000000 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4
  GNU_RELRO      0x000f28 0x08049f28 0x08049f28 0x000d8 0x000d8 R   0x1

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp 
   02     .interp .note.gnu.build-id .hash .gnu.hash .dynsym .dynstr .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 
   03     .ctors .dtors .jcr .dynamic .got.plt .data .bss 
   04     .dynamic 
   05     .note.gnu.build-id 
   06     .eh_frame_hdr 
   07     
   08     .ctors .dtors .jcr .dynamic 
$ readelf --dyn-syms conftest

Symbol table '.dynsym' contains 10 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000000     0 FUNC    GLOBAL DEFAULT  UND printf
     2: 00000000     0 FUNC    GLOBAL DEFAULT  UND fprintf
     3: 00000000     0 FUNC    GLOBAL DEFAULT  UND __errno_location
     4: 00000000     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main
     5: 0804a014     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
     6: 0804a020     0 NOTYPE  GLOBAL DEFAULT  ABS _end
     7: 08048390     0 NOTYPE  GLOBAL DEFAULT   11 _start
     8: 0804a014     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
     9: 0804a014     4 OBJECT  GLOBAL DEFAULT   22 stderr

> Did you set resource limits before running it?

No.
$ ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 29019
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 29019
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

> Are you using any strange kernel mods?

No. Stock openSUSE 12.1.
$ uname -srv
Linux 3.1.10-1.9-desktop #1 SMP PREEMPT Thu Apr 5 18:48:38 UTC 2012 (4a97ec8)

> What happened in gdb?

The stack trace in gdb is unusable.
$ gdb conftest
GNU gdb (GDB) SUSE (7.3-41.1.2)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-suse-linux".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /data/bruno/tmp/testdir3/conftest...done.
(gdb) set solib-search-path /arch/x86-linux/inst-musl/lib
(gdb) run
Starting program: /data/bruno/tmp/testdir3/conftest 
warning: Could not load shared library symbols for linux-gate.so.1.
Do you need "set solib-search-path" or "set sysroot"?

Program received signal SIGSEGV, Segmentation fault.
0xf7fc76c3 in fmt_fp () from /data/arch/x86-linux/inst-musl/lib/libc.so
(gdb) where
#0  0xf7fc76c3 in fmt_fp () from /data/arch/x86-linux/inst-musl/lib/libc.so
#1  0x00000000 in ?? ()

This is a bit useless, since libc.so is compiled without debugging information.
If I rebuild with "-O1 -g" instead of "-Os" and "-O3", I get this stack trace:

$ gdb conftest
GNU gdb (GDB) SUSE (7.3-41.1.2)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-suse-linux".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /data/bruno/tmp/testdir3/conftest...done.
(gdb) set solib-search-path /arch/x86-linux/inst-musl/lib
(gdb) run
Starting program: /data/bruno/tmp/testdir3/conftest 
warning: Could not load shared library symbols for linux-gate.so.1.
Do you need "set solib-search-path" or "set sysroot"?

Program received signal SIGSEGV, Segmentation fault.
fmt_fp (f=0xf7ff9200, y=0, w=0, p=5000000, fl=0, t=102) at src/stdio/vfprintf.c:326
326                     x = *d % i;
(gdb) where
#0  fmt_fp (f=0xf7ff9200, y=0, w=0, p=5000000, fl=0, t=102) at src/stdio/vfprintf.c:326
#1  0xf7fcacf3 in printf_core (f=0xf7ff9200, fmt=<optimized out>, ap=0xffffc13c, nl_arg=0xffffc09c, 
    nl_type=0xffffc114) at src/stdio/vfprintf.c:614
#2  0xf7fcb0eb in vfprintf (f=0xf7ff9200, fmt=0x80484f4 "%.5000000f", ap=0xffffc1a4 "") at src/stdio/vfprintf.c:659
#3  0xf7fcd967 in vprintf (fmt=0x80484f4 "%.5000000f", ap=0xffffc1a4 "") at src/stdio/vprintf.c:5
#4  0xf7fc8463 in printf (fmt=0x80484f4 "%.5000000f") at src/stdio/printf.c:9
#5  0x0804845f in main () at conftest.c:7
(gdb) info locals
x = <optimized out>
big = {524288, 0 <repeats 1750 times>, 4160552156, 0, 0, 0, 0, 0, 0, 0, 4160720884, 8, 8, 134513329, 4160343432, 
  134513332, 4160609540, 1, 0 <repeats 46 times>, 134513908, 4160721408, 4160517969, 4160727464, 134513908, 0, 0, 0, 
  0, 0, 4160720884, 4160711907, 0, 0, 4160524786}
a = 0xffffa2b0
d = 0x218b40
r = 0xffffa2b0
z = 0x218b44
e2 = 0
e = 0
i = <optimized out>
j = 9
l = <optimized out>
buf = '\000' <repeats 24 times>
s = <optimized out>
prefix = 0xf7ff6cb4 "0X+0X 0X-0x+0x 0x"
pl = 0
ebuf0 = '\000' <repeats 11 times>
ebuf = 0xffffa293 ""
estr = <optimized out>
(gdb) up
#1  0xf7fcacf3 in printf_core (f=0xf7ff9200, fmt=<optimized out>, ap=0xffffc13c, nl_arg=0xffffc09c, 
    nl_type=0xffffc114) at src/stdio/vfprintf.c:614
614                             l = fmt_fp(f, arg.f, w, p, fl, t);
(gdb) info locals
a = <optimized out>
z = 0xffffbff0 ""
s = 0x80484fe ""
l10n = 0
litpct = <optimized out>
fl = 0
w = 0
p = 5000000
arg = {i = 9223372036854775808, f = 1, p = 0x0}
argpos = -1
st = <optimized out>
ps = 0
cnt = 0
l = 0
i = <optimized out>
buf = "A\370\367\374\371\370\367\000\000\000\000\021", '\000' <repeats 27 times>, "\377", <incomplete sequence \367>
prefix = 0xf7ff6cd2 "-+   0X0x"
t = 102
pl = 0
wc = L"\xf7f9c62d\xf7f899ac"
ws = <optimized out>
mb = "\271\202\004\b"
(gdb) up
#2  0xf7fcb0eb in vfprintf (f=0xf7ff9200, fmt=0x80484f4 "%.5000000f", ap=0xffffc1a4 "") at src/stdio/vfprintf.c:659
659             ret = printf_core(f, fmt, &ap2, nl_arg, nl_type);
(gdb) info locals
ap2 = 0xffffc1ac ""
nl_type = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
nl_arg = {{i = 150189233701, f = 0, p = 0xf7f9d625}, {i = 4307434622, f = <invalid float value>, p = 0xbe3c7e}, {
    i = 4024693728518132, f = 0, p = 0x8049ff4}, {i = 0, f = <invalid float value>, p = 0x0}, {i = 98599429607984, 
    f = 0, p = 0xf7fa1230}, {i = 17868614760971370496, f = -0, p = 0x0}, {i = 17870160128724931592, f = 0, 
    p = 0xf7ff9408}, {i = 13791, f = 0, p = 0x35df}, {i = 47244701668, f = <invalid float value>, p = 0xefe4}, {
    i = 824633720832, f = 0, p = 0x0}}
internal_buf = "h\334\375\367", '\000' <repeats 12 times>"\364, \217\377\367\340\216\377\367\270\300\377\377\"\000\000\000:\310\371\367\270\300\377\377\000\000\000\000\210\000\000\000\260\202\004\b\000\224\377\367\000\000\000\000\000\000\000\000\364\217\377\367H\224\377\367@\301\377\377\000\340\377\377"
saved_buf = 0x0
ret = <optimized out>
__need_unlock = 0
(gdb) up
#3  0xf7fcd967 in vprintf (fmt=0x80484f4 "%.5000000f", ap=0xffffc1a4 "") at src/stdio/vprintf.c:5
5               return vfprintf(stdout, fmt, ap);
(gdb) info locals
No locals.
(gdb) up
#4  0xf7fc8463 in printf (fmt=0x80484f4 "%.5000000f") at src/stdio/printf.c:9
9               ret = vprintf(fmt, ap);
(gdb) info locals
ret = 9
ap = 0xffffc1a4 ""
(gdb) up
#5  0x0804845f in main () at conftest.c:7
7         ret = printf ("%.5000000f", 1.0);
(gdb) info locals
ret = 0
err = 0

The SIGSEGV occurs because d = 0x218b40 but the address ranges are these:
08048000-08049000 r-xp 00000000 08:05 26174991                           /data/bruno/tmp/testdir3/conftest
08049000-0804b000 rwxp 00000000 08:05 26174991                           /data/bruno/tmp/testdir3/conftest
f7f84000-f7ff8000 r-xp 00000000 08:05 26168372                           /data/arch/x86-linux/inst-musl/lib/libc.so
f7ff8000-f7ffa000 rwxp 00073000 08:05 26168372                           /data/arch/x86-linux/inst-musl/lib/libc.so
f7ffa000-f7ffe000 rwxp 00000000 00:00 0 
fffdc000-ffffe000 rwxp 00000000 00:00 0                                  [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0                                  [vdso]

> What if you run it under strace?

Yes. When it succeeds, the strace output looks normal. When it fails,
it's this:

$ strace ./conftest
execve("./conftest", ["./conftest"], [/* 133 vars */]) = 0
[ Process PID=2858 runs in 32 bit mode. ]
--- {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0xe7664} (Segmentation fault) ---
+++ killed by SIGSEGV (core dumped) +++
Speicherzugriffsfehler (Speicherabzug geschrieben)

Hope this helps.

Bruno

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.