Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make standalone curl leads to segfault

I would like to build a standalone version of `curl without any library dependency (even libc) for an embedded system with a very old libc version.

From current curl github, I configure the compilation with this command:

./configure --disable-shared --enable-static-nss --prefix=/tmp/curl LDFLAGS='-static -static-libgcc -Wl,-Bstatic -lc' LIBS='-lc -lssl -lcrypto -lz -ldl'
[...]
curl version:     7.50.2-DEV
  Host setup:       x86_64-pc-linux-gnu
  Install prefix:   /tmp/curl
  Compiler:         gcc
  SSL support:      enabled (OpenSSL)
  SSH support:      no      (--with-libssh2)
  zlib support:     enabled
  GSS-API support:  no      (--with-gssapi)
  TLS-SRP support:  enabled
  resolver:         default (--enable-ares / --enable-threaded-resolver)
  IPv6 support:     enabled
  Unix sockets support: enabled
  IDN support:      no      (--with-{libidn,winidn})
  Build libcurl:    Shared=no, Static=yes
  Built-in manual:  enabled
  --libcurl option: enabled (--disable-libcurl-option)
  Verbose errors:   enabled (--disable-verbose)
  SSPI support:     no      (--enable-sspi)
  ca cert bundle:   /etc/ssl/certs/ca-certificates.crt
  ca cert path:     no
  ca fallback:      no
  LDAP support:     no      (--enable-ldap / --with-ldap-lib / --with-lber-lib)
  LDAPS support:    no      (--enable-ldaps)
  RTSP support:     enabled
  RTMP support:     no      (--with-librtmp)
  metalink support: no      (--with-libmetalink)
  PSL support:      no      (libpsl not found)
  HTTP2 support:    disabled (--with-nghttp2)
  Protocols:        DICT FILE FTP FTPS GOPHER HTTP HTTPS IMAP IMAPS POP3 POP3S RTSP SMB SMBS SMTP SMTPS TELNET TFTP

Then during the make phase, I get the following warnings:

curl-tool_homedir.o: In function `homedir':
tool_homedir.c:(.text+0x60): warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
../lib/.libs/libcurl.a(libcurl_la-netrc.o): In function `Curl_parsenetrc':
netrc.c:(.text+0x3c3): warning: Using 'getpwuid_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
../lib/.libs/libcurl.a(libcurl_la-curl_addrinfo.o): In function `Curl_getaddrinfo_ex':
curl_addrinfo.c:(.text+0x73): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libcrypto.a(fips.o): In function `verify_checksums':
(.text+0x4e6): warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

I can continue and perform the make install to get the final binary.

The binary has no dependency:

$ ldd /tmp/curl/bin/curl
    not a dynamic executable
$ nm /tmp/curl/bin/curl | grep " U "
$ 

But the binary is not working at all:

$ /tmp/curl/bin/curl -version
Segmentation fault (core dumped)

Do you have any idea of the root cause issue?

EDIT 1: GDB output:

(gdb) run
Starting program: /tmp/curl/bin/curl 

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()

EDIT 2:

$ nm /tmp/curl/bin/curl | grep getpwuid
0000000000655770 T getpwuid
00000000006558f0 T __getpwuid_r
00000000006558f0 W getpwuid_r
00000000006558f0 T __new_getpwuid_r
0000000000663cf0 T __nscd_getpwuid_r

Maybe the issue comes from W:

W The symbol is a weak symbol that has not been specifically tagged as a weak object symbol. When a weak defined symbol is linked with a normal defined symbol, the normal defined symbol is used with no error. When a weak undefined symbol is linked and the symbol is not defined, the value of the weak symbol becomes zero with no error.

EDIT 3: If I remove the SSL linking I got the same warning for getpwuid but the binary is working:

./configure --disable-shared --enable-static-nss --prefix=/tmp/curl LDFLAGS='-static -static-libgcc -Wl,-Bstatic,-lc'

ldd /tmp/curl/bin/curl
    not a dynamic executable
 /tmp/curl/bin/curl --version
curl 7.50.2-DEV (x86_64-pc-linux-gnu) libcurl/7.50.2-DEV zlib/1.2.8
Protocols: dict file ftp gopher http imap pop3 rtsp smtp telnet tftp 
Features: IPv6 Largefile libz UnixSockets 

 nm /tmp/curl/bin/curl | grep getpwuid
00000000004f52d0 T getpwuid
00000000004f5450 T __getpwuid_r
00000000004f5450 W getpwuid_r
00000000004f5450 T __new_getpwuid_r
0000000000502cd0 T __nscd_getpwuid_r

But I need to add SSL for HTTPS support so the issue is still open.

EDIT 4: The issue is directly linked to nss. Strange point is that ./configure --prefix=/tmp/curl --disable-shared --enable-static-nss LDFLAGS='-static -static-libgcc -Wl,-Bstatic' LIBS='-ls' produces a working standalone executable but without SSL. The nss issues is due to the SSL linking.

like image 425
Julio Avatar asked Aug 25 '16 21:08

Julio


1 Answers

Pull in the source development version of openssl https://www.openssl.org/ and recompile it for static linkage (ends with a '.a' instead of a '.so'). Then rebuild curl, linking to the openssl static library you built.

You know that libssl is giving you problems, but it may not be the only library that is. When you find the next library that is giving you problems, do the same for it: pull in the source development version and rebuild it for static linkage.

like image 191
Arie Jefferson Avatar answered Nov 25 '22 13:11

Arie Jefferson