Bug 65029

Summary: Segfault with 0.5+, spt_init() at setproctitle.c:138
Product: libbsd Reporter: Daniel <leva>
Component: libbsdAssignee: Guillem Jover <guillem>
Status: RESOLVED FIXED QA Contact:
Severity: major    
Priority: medium    
Version: unspecified   
Hardware: x86 (IA32)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:
Attachments: Force spt_init into the .init_array section

Description Daniel 2013-05-27 08:57:22 UTC
Hi!

I'm trying to use the fresh 0.5.[01] libbsd, and when starting the program
that I link with it, I get a segfault. I've tried with two different
softwares that link against libbsd, and got the same segmentation fault:

[...]
Program terminated with signal 11, Segmentation fault.
#0  0xb75f92c8 in spt_init (argc=-1218455576, argv=0x1, envp=0x1) at setproctitle.c:138
138             base = argv[0];
(gdb) bt
#0  0xb75f92c8 in spt_init (argc=-1218455576, argv=0x1, envp=0x1) at setproctitle.c:138
#1  0xb75faf6d in __do_global_ctors_aux () from /usr/lib/libbsd.so.0
#2  0xb75f1a2c in _init () from /usr/lib/libbsd.so.0
#3  0xb77fe000 in ?? () from /lib/ld-linux.so.2
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) bt full
#0  0xb75f92c8 in spt_init (argc=-1218455576, argv=0x1, envp=0x1) at setproctitle.c:138
        base = 0xb726e496 <__ctype_init+6> "\201\303j\353\025"
        end = 0xb725e666 <_init+102> "\203\304\034[^_]\303f\220\213\203\334\377\377\377\213\223,\377\377\377?@"
        nul = 0xb73cd000 "\274}\030"
        tmp = 0x0
        i = -1220751360
        error = -1075053569
#1  0xb75faf6d in __do_global_ctors_aux () from /usr/lib/libbsd.so.0
No symbol table info available.
#2  0xb75f1a2c in _init () from /usr/lib/libbsd.so.0
No symbol table info available.
#3  0xb77fe000 in ?? () from /lib/ld-linux.so.2
No symbol table info available.
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) list
133     spt_init(int argc, char *argv[], char *envp[])
134     {
135             char *base, *end, *nul, *tmp;
136             int i, error;
137
138             base = argv[0];
139             if (base == NULL)
140                     return;
141
142             nul = &base[strlen(base)];
(gdb) quit


Everything worked fine with 0.4.2 -- but of course, it didn't have setproctitle.
Comment 1 Daniel 2013-05-27 09:03:28 UTC
The system is a Slackware -current.
$ uname -srvmpio 
Linux 3.8.13-smp #2 SMP Sun May 12 19:59:29 CDT 2013 i686 Intel(R) Core(TM) i7-2630QM CPU @ 2.00GHz GenuineIntel GNU/Linux
$ gcc -dumpversion
4.8.0
Comment 2 Guillem Jover 2013-05-27 20:19:17 UTC
Hi!

(In reply to comment #0)
> I'm trying to use the fresh 0.5.[01] libbsd, and when starting the program
> that I link with it, I get a segfault. I've tried with two different
> softwares that link against libbsd, and got the same segmentation fault:
> 
> [...]
> Program terminated with signal 11, Segmentation fault.
> #0  0xb75f92c8 in spt_init (argc=-1218455576, argv=0x1, envp=0x1) at
> setproctitle.c:138
> 138             base = argv[0];
> (gdb) bt
> #0  0xb75f92c8 in spt_init (argc=-1218455576, argv=0x1, envp=0x1) at
> setproctitle.c:138
> #1  0xb75faf6d in __do_global_ctors_aux () from /usr/lib/libbsd.so.0

Ok, so this looks like the spt_init constructor function ends up in the .ctor
section as it's being called from the code handling that section, instead of
in .init_array, and the calls into the .ctor function do not get passed the
needed arguments.

Could you check your binary with something like:

  objdump -s -j .init_array -j .init -j .ctor program-name

> Everything worked fine with 0.4.2 -- but of course, it didn't have
> setproctitle.

What libc and binutils versions are you using?

I guess I'll have to make sure in configure that the constructor
functions ends up in the correct section (i.e. not in .ctor), to avoid this.
Comment 3 Daniel 2013-05-28 08:11:52 UTC
(In reply to comment #2)
> Hi!
> 
> (In reply to comment #0)
> > I'm trying to use the fresh 0.5.[01] libbsd, and when starting the program
> > that I link with it, I get a segfault. I've tried with two different
> > softwares that link against libbsd, and got the same segmentation fault:
> > 
> > [...]
> > Program terminated with signal 11, Segmentation fault.
> > #0  0xb75f92c8 in spt_init (argc=-1218455576, argv=0x1, envp=0x1) at
> > setproctitle.c:138
> > 138             base = argv[0];
> > (gdb) bt
> > #0  0xb75f92c8 in spt_init (argc=-1218455576, argv=0x1, envp=0x1) at
> > setproctitle.c:138
> > #1  0xb75faf6d in __do_global_ctors_aux () from /usr/lib/libbsd.so.0
> 
> Ok, so this looks like the spt_init constructor function ends up in the .ctor
> section as it's being called from the code handling that section, instead of
> in .init_array, and the calls into the .ctor function do not get passed the
> needed arguments.

Hey Guillem,

Thanks for the explanation!

> Could you check your binary with something like:
> 
>   objdump -s -j .init_array -j .init -j .ctor program-name

Sure:


./kc:     file format elf32-i386

Contents of section .init:
 8049b28 5383ec08 e83f0800 0081c3df e500008b  S....?..........
 8049b38 83fcffff ff85c074 05e83a01 0000e805  .......t..:.....
 8049b48 090000e8 809e0000 83c4085b c3        ...........[.   


/bin/pdksh:     file format elf32-i386

Contents of section .init:
 80498f0 5383ec08 e8770800 0081c3ef 9703008b  S....w..........
 8049900 83fcffff ff85c074 05e87203 0000e83d  .......t..r....=
 8049910 090000e8 48f40200 83c4085b c3        ....H......[.   

> > Everything worked fine with 0.4.2 -- but of course, it didn't have
> > setproctitle.
> 
> What libc and binutils versions are you using?

glibc is at 2.17, and my binutils package is version 2.23.52.0.1.

> I guess I'll have to make sure in configure that the constructor
> functions ends up in the correct section (i.e. not in .ctor), to avoid this.
Comment 4 Guillem Jover 2013-05-28 16:48:54 UTC
(In reply to comment #3)
> (In reply to comment #2)
> > Could you check your binary with something like:
> > 
> >   objdump -s -j .init_array -j .init -j .ctor program-name

Sorry that should have been (.ctors instead of .ctor):

  objdump -s -j .init_array -j .init -j .ctors program-name

In any case, the problem here is that there's no .init_array section.

> > > Everything worked fine with 0.4.2 -- but of course, it didn't have
> > > setproctitle.
> > 
> > What libc and binutils versions are you using?
> 
> glibc is at 2.17, and my binutils package is version 2.23.52.0.1.

Hmm, ok could you check if your distribution builds for binutils and gcc
have perhaps disabled the .init_array/.fini_array native support, there's
a flag for those (--enable-initfini-array), or maybe the checks to see if
these are supported failed?

Meanwhile, a workaround in libbsd until you figure out why .init_array is
not generated on your distribution could be the attached patch. I guess I
can make libbsd switch to use that if the constructor is not placed in
.init_array either by gcc directly, or by ld converting .ctors to .init_array.
Comment 5 Guillem Jover 2013-05-28 16:49:56 UTC
Created attachment 79908 [details] [review]
Force spt_init into the .init_array section
Comment 6 Daniel 2013-05-28 17:17:13 UTC
(In reply to comment #4)
[...]
> > >   objdump -s -j .init_array -j .init -j .ctor program-name
> 
> Sorry that should have been (.ctors instead of .ctor):
> 
>   objdump -s -j .init_array -j .init -j .ctors program-name

Rrrright, should've catch that, sorry ... :)


$ objdump -s -j .init_array -j .init -j .ctors ./kc

./kc:     file format elf32-i386

Contents of section .init:
 8049b28 5383ec08 e83f0800 0081c3df e500008b  S....?..........
 8049b38 83fcffff ff85c074 05e83a01 0000e805  .......t..:.....
 8049b48 090000e8 809e0000 83c4085b c3        ...........[.   
Contents of section .ctors:
 8058000 ffffffff 00000000                    ........        


$ objdump -s -j .init_array -j .init -j .ctors /bin/pdksh

/bin/pdksh:     file format elf32-i386

Contents of section .init:
 80498f0 5383ec08 e86b0800 0081c3ef a703008b  S....k..........
 8049900 83fcffff ff85c074 05e87203 0000e82d  .......t..r....-
 8049910 090000e8 08fe0200 83c4085b c3        ...........[.   
Contents of section .ctors:
 8084000 ffffffff 00000000                    ........

> In any case, the problem here is that there's no .init_array section.

[...]
> > glibc is at 2.17, and my binutils package is version 2.23.52.0.1.
> 
> Hmm, ok could you check if your distribution builds for binutils and gcc
> have perhaps disabled the .init_array/.fini_array native support, there's
> a flag for those (--enable-initfini-array), or maybe the checks to see if
> these are supported failed?

Your suspicion was right. From the binutils build script for my distribution:

[...]
# The --enable-initfini-array option was added in binutils-2.21.51.0.3.
# This option currently causes a world of hurt trying to compile glibc,
# and might break static libraries or cause other ill effects.  There
# is an upstream patch for glibc but it does not avoid all of the known
# problems (and there may be some unknown ones, too), so we will avoid
# introducing this feature for now.
# References:
# http://sourceware.org/bugzilla/show_bug.cgi?id=12343
# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=46770
NO_INITFINI=" --disable-initfini-array "
[...]
./configure \
[...]
  $NO_INITFINI \
[...]


> Meanwhile, a workaround in libbsd until you figure out why .init_array is
> not generated on your distribution could be the attached patch. I guess I
> can make libbsd switch to use that if the constructor is not placed in
> .init_array either by gcc directly, or by ld converting .ctors to
> .init_array.

The attached patch with the workaround solved this issue for me. objdump(1) shows the same
stuff, but now the binaries run.
Thanks!


Daniel
Comment 7 Guillem Jover 2013-06-08 16:46:17 UTC
Fixed in 0.5.2.

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.