Bug 21975 - gethostbyname always segfaults if linked statically
Summary: gethostbyname always segfaults if linked statically
Status: RESOLVED FIXED
Alias: None
Product: glibc
Classification: Unclassified
Component: network (show other bugs)
Version: 2.24
: P2 normal
Target Milestone: 2.34
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-08-18 19:18 UTC by Horst Schirmeier
Modified: 2022-09-06 19:12 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed: 2017-08-18 00:00:00
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Horst Schirmeier 2017-08-18 19:18:14 UTC
With glibc 2.24 (reproducible on 64-bit Debian 9 or Ubuntu 17.04), gethostbyname() always segfaults if the binary was linked statically:

$ echo -e "#include <netdb.h>\nint main(void){gethostbyname(\"foo\");}" > foo.c && gcc -g -static foo.c && ./a.out
/tmp/ccp8JNGC.o: In function `main':
/tmp/foo.c:2: warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
Segmentation fault (core dumped)
$ gdb -c core
GNU gdb (Ubuntu 7.12.50.20170314-0ubuntu1.1) 7.12.50.20170314-git
[...]
[New LWP 28640]
Core was generated by `./a.out'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x0000000000000000 in ?? ()
(gdb) bt
#0  0x0000000000000000 in ?? ()
#1  0x00007f8d940bbf90 in ?? ()
#2  0x00007fff8e02d0a0 in ?? ()
#3  0x0000000000000010 in ?? ()
#4  0x0000000000800000 in ?? ()
#5  0xffffffffffffffff in ?? ()
#6  0x00007f8d940bbbd0 in ?? ()
#7  0x0000000180000000 in ?? ()
#8  0x0000000000000000 in ?? ()

Unlike bug 10652, -lpthread is not needed to reproduce this issue.
Comment 1 Andreas Schwab 2017-08-18 19:32:18 UTC
I cannot reproduce that with 2.25.
Comment 2 Florian Weimer 2017-08-18 20:17:20 UTC
I cannot reproduce with 2.24 or 2.25, which is a pity because Fedora has a static glibc with debugging symbols.  It could be a Debian or Ubuntu patch.

You need to link with debugging symbols and post a backtrace with symbols at least.
Comment 3 Horst Schirmeier 2017-08-18 21:00:06 UTC
To me these backtrace addresses look like the stack is smashed, i.e. debug symbols wouldn't help.  But in fact it looks like Ubuntu's libc.a does come with debug symbols.

Interestingly, when running a.out directly in gdb instead of loading the coredump, the backtrace makes more sense:

$ gdb a.out
GNU gdb (Ubuntu 7.12.50.20170314-0ubuntu1.1) 7.12.50.20170314-git                                                                                                                    
[...]
Reading symbols from a.out...done.                                                                                                                                                   
(gdb) run                                                                                                                                                                            
Starting program: /tmp/a.out                                                                                                                                                         
[Thread debugging using libthread_db enabled]                                                                                                                                        
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".                                                                                                           
                                                                                                                                                                                     
Program received signal SIGSEGV, Segmentation fault.                                                                                                                                 
0x0000000000000000 in ?? ()                                                                                                                                                          
(gdb) bt                                                                                                                                                                             
#0  0x0000000000000000 in ?? ()                                                                                                                                                      
#1  0x00007ffff6c30f90 in __pthread_initialize_minimal_internal () at nptl-init.c:471                                                                                                
#2  0x00007ffff6c30571 in _init () at ../sysdeps/x86_64/crti.S:72                                                                                                                    
#3  0x00007ffff747ef70 in ?? () from /lib/x86_64-linux-gnu/libnss_resolve.so.2                                                                                                       
#4  0x0000000000490cca in call_init.part ()                                                                                                                                          
#5  0x0000000000490e85 in _dl_init ()                                                                                                                                                
#6  0x0000000000487056 in dl_open_worker ()                                                                                                                                          
#7  0x00000000004847e4 in _dl_catch_error ()                                                                                                                                         
#8  0x00000000004869ac in _dl_open ()                                                                                                                                                
#9  0x000000000044a0f2 in do_dlopen ()
#10 0x00000000004847e4 in _dl_catch_error ()
#11 0x000000000044a2de in __libc_dlopen_mode ()
#12 0x0000000000446628 in __nss_next2 ()
#13 0x0000000000443b1a in gethostbyname_r ()
#14 0x0000000000443863 in gethostbyname ()
#15 0x0000000000400b6e in main () at foo.c:2
Comment 4 Florian Weimer 2017-08-18 21:18:43 UTC
Is there a reason why you use systemd-resolved?

libnss_resolve probably links against libpthread (at least the systemd components I've seen all do that), and loading that via dlopen from a statically linked binary is problematic.

Late loading of libpthread into a statically linked program is very difficult to get right because preparing for that invalidates a lot of optimizations one wants to do when linking statically.  For the time being, you'll just have to use NSS modules which do not link against libpthread.
Comment 5 Horst Schirmeier 2017-08-19 11:23:41 UTC
(In reply to Florian Weimer from comment #4)
> Is there a reason why you use systemd-resolved?
That's the Debian 9 and Ubuntu 17.04 default, I'm certainly not doing this by choice.

> libnss_resolve probably links against libpthread (at least the systemd
> components I've seen all do that), and loading that via dlopen from a
> statically linked binary is problematic.
> 
> Late loading of libpthread into a statically linked program is very
> difficult to get right because preparing for that invalidates a lot of
> optimizations one wants to do when linking statically.  For the time being,
> you'll just have to use NSS modules which do not link against libpthread.
You don't happen to know which Debian/Ubuntu packages provide such modules? :-)
Comment 6 Horst Schirmeier 2017-08-20 15:30:50 UTC
Debian bugreport (I won't bother reporting this for Ubuntu, their bugtracker seems to be write only): https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=872727
Comment 7 Aurelien Jarno 2017-08-20 16:47:30 UTC
(In reply to Florian Weimer from comment #2)
> I cannot reproduce with 2.24 or 2.25, which is a pity because Fedora has a
> static glibc with debugging symbols.  It could be a Debian or Ubuntu patch.
> 
> You need to link with debugging symbols and post a backtrace with symbols at
> least.

That's reproducible on my fedora system, which got libnss-myhostname enabled by default. Same kind of backtrace:

#0  0x0000000000000000 in ?? ()
#1  0x00007ffff6549040 in __pthread_initialize_minimal_internal () from /lib64/libpthread.so.0
#2  0x00007ffff65485f9 in _init () from /lib64/libpthread.so.0
#3  0x00007ffff72b6898 in ?? () from /lib64/libnss_myhostname.so.2
#4  0x000000000048f94a in call_init.part ()
#5  0x000000000048fb0d in _dl_init ()
#6  0x0000000000485d06 in dl_open_worker ()
#7  0x00000000004834e4 in _dl_catch_error ()
#8  0x0000000000485669 in _dl_open ()
#9  0x00000000004491d2 in do_dlopen ()
#10 0x00000000004834e4 in _dl_catch_error ()
#11 0x00000000004493be in __libc_dlopen_mode ()
#12 0x0000000000445800 in __nss_next2 ()
#13 0x0000000000442dfa in gethostbyname_r ()
#14 0x0000000000442b43 in gethostbyname ()
#15 0x0000000000400b6c in main () at foo.c:2
Comment 8 Horst Schirmeier 2017-08-20 17:01:50 UTC
Ah, good catch.  Doesn't crash anymore after uninstalling libnss-myhostname.
Comment 9 Horst Schirmeier 2017-08-20 17:03:18 UTC
... on Debian, that is.  On Ubuntu 17.04, it still crashes with the aforementioned backtrace.
Comment 10 Aurelien Jarno 2022-09-06 19:12:47 UTC
Since glibc 2.34, libpthread has been integrated into libc. As a side effect this fixes this bug.