[2.15~pre6] regression: crashes in dlopen()

Bug #919202 reported by Martin Pitt
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
GLibC
Fix Released
Critical
eglibc (Ubuntu)
Fix Released
High
Matthias Klose

Bug Description

I have used eglibc 2.15~pre6-0ubuntu4 from https://launchpad.net/~ubuntu-toolchain-r/+archive/glibc/+packages since last week. Yesterday I noticed that this causes a crash in the gdk-pixbuf loader cache when it tries to examine the SVG one.

This can be reduced to this test case:

With precise's libc6 2.13, it works:

/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/gdk-pixbuf-query-loaders /usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.so
# GdkPixbuf Image Loader Modules file
# Automatically generated file, do not edit
# Created by gdk-pixbuf-query-loaders from gdk-pixbuf-2.25.0
#
"/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.so"
"svg" 2 "gdk-pixbuf" "Scalable Vector Graphics" "LGPL"
"image/svg+xml" "image/svg" "image/svg-xml" "image/vnd.adobe.svg+xml" "text/xml-svg" "image/svg+xml-compressed" ""
"svg" "svgz" "svg.gz" ""
" <svg" "* " 100
" <!DOCTYPE svg" "* " 100

With the PPA version it crashes:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000005446 in ?? ()
(gdb) bt
#0 0x0000000000005446 in ?? ()
#1 0x00007ffff5137fc5 in floor ()
    at ../sysdeps/x86_64/fpu/multiarch/s_floor.S:26
#2 0x00007ffff7de6a2b in ?? () from /lib64/ld-linux-x86-64.so.2
#3 0x00007ffff7ded936 in ?? () from /lib64/ld-linux-x86-64.so.2
#4 0x00007ffff7de9126 in ?? () from /lib64/ld-linux-x86-64.so.2
#5 0x00007ffff7ded2ca in ?? () from /lib64/ld-linux-x86-64.so.2
#6 0x00007ffff7107f26 in dlopen_doit (a=0x7fffffffe280) at dlopen.c:67
#7 0x00007ffff7de9126 in ?? () from /lib64/ld-linux-x86-64.so.2
#8 0x00007ffff710852f in _dlerror_run (operate=0x7ffff7107ec0 <dlopen_doit>,
    args=0x7fffffffe280) at dlerror.c:164
#9 0x00007ffff7107fc1 in __dlopen (file=<optimized out>, mode=<optimized out>)
    at dlopen.c:88
#10 0x00007ffff7bd76fc in _g_module_open (bind_local=<optimized out>,
    bind_lazy=<optimized out>,
    file_name=0x605000 "/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.so")
    at /build/buildd/glib2.0-2.31.10/./gmodule/gmodule-dl.c:99
#11 g_module_open (
    file_name=0x604630 "/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.so", flags=<optimized out>)
    at /build/buildd/glib2.0-2.31.10/./gmodule/gmodule.c:584
#12 0x00000000004010a0 in ?? ()
#13 0x0000000000400d94 in ?? ()
#14 0x00007ffff732c76d in __libc_start_main (main=0x400cf0, argc=2,
    ubp_av=0x7fffffffe4e8, init=<optimized out>, fini=<optimized out>,
    rtld_fini=<optimized out>, stack_end=0x7fffffffe4d8) at libc-start.c:226

Unfortunately the backtrace is rather useless. I do have the matching libc6-dbg, it just doesn't seem to help here.

Martin Pitt (pitti)
description: updated
Revision history for this message
Ppluzhnikov-google (ppluzhnikov-google) wrote :

The reason for "useless" stack trace is a GDB bug:
http://sourceware.org/bugzilla/show_bug.cgi?id=9538

You should be able to get a more useful info by using explicit

  add-symbol-file /usr/lib/debug/lib/x86_64-linux-gnu/ld-2.15.so <ld-linux-load-address>

(where ld-linux-load-address is available from "info shared")

Changed in eglibc (Ubuntu):
assignee: nobody → Matthias Klose (doko)
Revision history for this message
Ppluzhnikov-google (ppluzhnikov-google) wrote :

The crash stack trace is:

(gdb) bt
#0 0x0000000000005446 in ?? ()
#1 0x00007ffff5137fc5 in floor () at ../sysdeps/x86_64/fpu/multiarch/s_floor.S:26
#2 0x00007ffff7de6a2b in elf_machine_rela (sym=0x7ffff511ec88, skip_ifunc=0, reloc_addr_arg=0x7ffff41c5060, version=<optimized out>, map=0x60b090, reloc=<optimized out>)
    at ../sysdeps/x86_64/dl-machine.h:302
#3 elf_dynamic_do_Rela (skip_ifunc=0, lazy=<optimized out>, nrelative=<optimized out>, relsize=<optimized out>, reladdr=<optimized out>, map=0x60b090) at do-rel.h:146
#4 _dl_relocate_object (scope=0x60b3e8, reloc_mode=<optimized out>, consider_profiling=0) at dl-reloc.c:265
#5 0x00007ffff7ded936 in dl_open_worker (a=0x7fffffffd690) at dl-open.c:338
#6 0x00007ffff7de9126 in _dl_catch_error (objname=0x7fffffffd6d8, errstring=0x7fffffffd6e0, mallocedp=0x7fffffffd6ef, operate=0x7ffff7ded6b0 <dl_open_worker>, args=0x7fffffffd690)
    at dl-error.c:178
#7 0x00007ffff7ded2ca in _dl_open (file=0x605000 "/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.so", mode=-2147483390, caller_dlopen=0x7ffff7bd76fc, nsid=-2,
    argc=2, argv=<optimized out>, env=0x7fffffffdb30) at dl-open.c:575
#8 0x00007ffff7107f26 in dlopen_doit (a=0x7fffffffd8b0) at dlopen.c:67
#9 0x00007ffff7de9126 in _dl_catch_error (objname=0x6047e0, errstring=0x6047e8, mallocedp=0x6047d8, operate=0x7ffff7107ec0 <dlopen_doit>, args=0x7fffffffd8b0) at dl-error.c:178
#10 0x00007ffff710852f in _dlerror_run (operate=0x7ffff7107ec0 <dlopen_doit>, args=0x7fffffffd8b0) at dlerror.c:164
#11 0x00007ffff7107fc1 in __dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:88
#12 0x00007ffff7bd76fc in _g_module_open (bind_local=<optimized out>, bind_lazy=<optimized out>,
    file_name=0x605000 "/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.so") at /build/buildd/glib2.0-2.31.10/./gmodule/gmodule-dl.c:99
#13 g_module_open (file_name=0x604630 "/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-svg.so", flags=<optimized out>)
    at /build/buildd/glib2.0-2.31.10/./gmodule/gmodule.c:584
#14 0x00000000004010a0 in ?? ()
#15 0x0000000000400d94 in ?? ()
#16 0x00007ffff732c76d in __libc_start_main (main=0x400cf0, argc=2, ubp_av=0x7fffffffdb18, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffdb08)
    at libc-start.c:226

The crash is happening while relocating /usr/lib/x86_64-linux-gnu/libpixman-1.so.0,
while processing this symbol (refsym):
    17: 0000000000000000 0 FUNC GLOBAL DEFAULT UND floor@GLIBC_2.2.5 (4)

The symbol that we are trying to bind this to (sym) is an IFUNC in
/lib/x86_64-linux-gnu/libm.so.6:

    60: 000000000001afc0 32 IFUNC WEAK DEFAULT 13 floor@@GLIBC_2.2.5

The problem is that we CALL from __floor to *unrelocated* address (0x5446)
of __get_cpu_features (that is, libm.so.6 hasn't been relocated yet.

I have not been able to create a simple reproducer ;-(

Revision history for this message
In , Ppluzhnikov-google (ppluzhnikov-google) wrote :

The test is reduced from
https://bugs.launchpad.net/ubuntu/+source/eglibc/+bug/919202

Reproduces with current git trunk.

// foo.c
#include <math.h>
int foo (double d) { return floor (d) != 0; }

// bar.c
int bar () { return foo (); }

// main.c
#include <dlfcn.h>
#include <stdio.h>

int
main (int argc, char *argv[])
{
  const char *lib = "./bar.so";
  if (argc > 1) lib = argv[1];
  void *h = dlopen (lib, RTLD_NOW); // RTLD_LAZY -> no bug
  if (h == 0)
    {
      puts (dlerror ());
      return 1;
    }
  return 0;
}

gcc -fPIC -shared -fno-builtin -o foo.so foo.c -lm &&
gcc -fPIC -shared -o bar.so -Wl,--no-as-needed -lm ./foo.so bar.c &&
gcc -g main.c -ldl

gdb -q ./a.out

Program received signal SIGSEGV, Segmentation fault.
0x0000000000005446 in ?? ()
(gdb) bt
#0 0x0000000000005446 in ?? ()
#1 0x00007ffff7351005 in floor () at ../sysdeps/x86_64/fpu/multiarch/s_floor.S:26
#2 0x00007ffff7de738f in elf_machine_rela (sym=0x7ffff7338c88, skip_ifunc=<optimized out>, reloc_addr_arg=0x7ffff7336008, version=<optimized out>, map=0x602af0,
    reloc=<optimized out>) at ../sysdeps/x86_64/dl-machine.h:302
#3 elf_dynamic_do_Rela (skip_ifunc=<optimized out>, lazy=<optimized out>, nrelative=<optimized out>, relsize=<optimized out>, reladdr=<optimized out>, map=0x602af0)
    at do-rel.h:146
#4 _dl_relocate_object (scope=0x602e48, reloc_mode=<optimized out>, consider_profiling=0) at dl-reloc.c:265
#5 0x00007ffff7deda23 in dl_open_worker (a=0x7fffffffd400) at dl-open.c:338
#6 0x00007ffff7de9686 in _dl_catch_error (objname=0x7fffffffd3f0, errstring=0x7fffffffd3f8, mallocedp=0x7fffffffd3ef, operate=0x7ffff7ded7c0 <dl_open_worker>,
    args=0x7fffffffd400) at dl-error.c:178
#7 0x00007ffff7ded36c in _dl_open (file=0x40080c "./bar.so", mode=-2147483646, caller_dlopen=<optimized out>, nsid=-2, argc=1, argv=0x7fffffffd748, env=0x7fffffffd758)
    at dl-open.c:575
#8 0x00007ffff7bd7f26 in dlopen_doit (a=0x7fffffffd610) at dlopen.c:67
#9 0x00007ffff7de9686 in _dl_catch_error (objname=0x7ffff7dda0d0, errstring=0x7ffff7dda0d8, mallocedp=0x7ffff7dda0c8, operate=0x7ffff7bd7ec0 <dlopen_doit>, args=0x7fffffffd610)
    at dl-error.c:178
#10 0x00007ffff7bd84dc in _dlerror_run (operate=0x7ffff7bd7ec0 <dlopen_doit>, args=0x7fffffffd610) at dlerror.c:164
#11 0x00007ffff7bd7fc1 in __dlopen (file=<optimized out>, mode=<optimized out>) at dlopen.c:88
#12 0x00000000004006f1 in main (argc=1, argv=0x7fffffffd748) at main.c:8

What appears to be happening is that __floor (IFUNC) jumps to *unrelocated*
GOT entry for __get_cpu_features.

Revision history for this message
Ppluzhnikov-google (ppluzhnikov-google) wrote :

Got a trivial reproducer and filed upstream bug:
http://sourceware.org/bugzilla/show_bug.cgi?id=13618

Matthias Klose (doko)
Changed in eglibc (Ubuntu):
importance: Undecided → High
status: New → Triaged
Revision history for this message
In , Andreas Jaeger (jaegerandi) wrote :

*** Bug 13580 has been marked as a duplicate of this bug. ***

Revision history for this message
In , Andreas Jaeger (jaegerandi) wrote :

Thanks for the testcase.

Changed in glibc:
importance: Unknown → Critical
status: Unknown → Confirmed
Revision history for this message
In , Drepper-fsp (drepper-fsp) wrote :

I added a patch.

Revision history for this message
In , Mike Frysinger (vapier) wrote :

i suspect this is said commit:
http://sourceware.org/git/?p=glibc.git;a=commit;h=6ee65ed6ddbf04402fad0bec6aa9c73b9d982ae4

seems to fix my known failing test case (svn)

Changed in glibc:
status: Confirmed → Fix Released
Revision history for this message
In , Ppluzhnikov-google (ppluzhnikov-google) wrote :

*** Bug 13633 has been marked as a duplicate of this bug. ***

Revision history for this message
Matthias Klose (doko) wrote :

fixed in the ppa build

Changed in eglibc (Ubuntu):
status: Triaged → Fix Released
Revision history for this message
In , Ppluzhnikov-google (ppluzhnikov-google) wrote :

*** Bug 14133 has been marked as a duplicate of this bug. ***

Revision history for this message
In , Ppluzhnikov-google (ppluzhnikov-google) wrote :

(In reply to comment #6)
> *** Bug 14133 has been marked as a duplicate of this bug. ***

In PR13618, Marc-Antoine Perennou asks for the fix to be back-ported to 15.1 branch.

Revision history for this message
In , Jackie-rosen (jackie-rosen) wrote :

*** Bug 260998 has been marked as a duplicate of this bug. ***
Seen from the domain http://volichat.com
Page where seen: http://volichat.com/adult-chat-rooms
Marked for reference. Resolved as fixed @bugzilla.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.