Opened 13 months ago

Last modified 2 weeks ago

#27802 new defect

OpenSSL 1.1.0 issue during static link

Reported by: cretz Owned by:
Priority: Medium Milestone: Tor: 0.4.2.x-final
Component: Core Tor/Tor Version:
Severity: Normal Keywords: static, 029-backport, 032-unreached-backport, 033-unreached-backport 042-can?
Cc: Actual Points:
Parent ID: #6623 Points:
Reviewer: Sponsor:

Description

Here's my configure call (using Tor 0.3.5.1-alpha in my case):

sh ./configure --prefix=/home/cretz/work/bine/gopath/src/github.com/cretz/tor-static/tor/dist --disable-gcc-hardening --disable-system-torrc --disable-asciidoc --enable-static-libevent --with-libevent-dir=/home/cretz/work/bine/gopath/src/github.com/cretz/tor-static/tor/../libevent/dist --enable-static-openssl --with-openssl-dir=/home/cretz/work/bine/gopath/src/github.com/cretz/tor-static/tor/../openssl/dist --enable-static-zlib --with-zlib-dir=/home/cretz/work/bine/gopath/src/github.com/cretz/tor-static/tor/../openssl/dist --enable-static-tor

Note, this all works fine with OpenSSL 1.0.x. Running gets:

configure: Now, we'll look for OpenSSL >= 1.0.1
checking for openssl directory... configure: WARNING: Could not find a linkable openssl.  If you have it installed somewhere unusual, you can specify an explicit path using --with-openssl-dir
configure: WARNING: On Debian, you can install openssl using "apt-get install libssl-dev"
configure: error: Missing libraries; unable to proceed.

Looking in config.log where it's checking OpenSSL:

configure:9656: Now, we'll look for OpenSSL >= 1.0.1
configure:9677: checking for openssl directory
configure:9732: gcc -o conftest -g -O2 -static -I/home/cretz/work/bine/gopath/src/github.com/cretz/tor-static/tor/../openssl/dist/include  -L/home/cretz/work/bine/gopath/src/github.com/cretz/tor-static/tor/../openssl/dist/lib  conftest.c -lpthread -ldl  -lssl -lcrypto   >&5
/home/cretz/work/bine/gopath/src/github.com/cretz/tor-static/tor/../openssl/dist/lib/libcrypto.a(b_addr.o): In function `BIO_lookup':
b_addr.c:(.text+0xc9c): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/home/cretz/work/bine/gopath/src/github.com/cretz/tor-static/tor/../openssl/dist/lib/libcrypto.a(b_sock.o): In function `BIO_gethostbyname':
b_sock.c:(.text+0x71): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/home/cretz/work/bine/gopath/src/github.com/cretz/tor-static/tor/../openssl/dist/lib/libcrypto.a(threads_pthread.o): In function `CRYPTO_THREAD_lock_new':
threads_pthread.c:(.text+0x25): undefined reference to `pthread_rwlock_init'
/home/cretz/work/bine/gopath/src/github.com/cretz/tor-static/tor/../openssl/dist/lib/libcrypto.a(threads_pthread.o): In function `CRYPTO_THREAD_read_lock':
threads_pthread.c:(.text+0x65): undefined reference to `pthread_rwlock_rdlock'
/home/cretz/work/bine/gopath/src/github.com/cretz/tor-static/tor/../openssl/dist/lib/libcrypto.a(threads_pthread.o): In function `CRYPTO_THREAD_write_lock':
threads_pthread.c:(.text+0x85): undefined reference to `pthread_rwlock_wrlock'
/home/cretz/work/bine/gopath/src/github.com/cretz/tor-static/tor/../openssl/dist/lib/libcrypto.a(threads_pthread.o): In function `CRYPTO_THREAD_unlock':
threads_pthread.c:(.text+0xa5): undefined reference to `pthread_rwlock_unlock'
/home/cretz/work/bine/gopath/src/github.com/cretz/tor-static/tor/../openssl/dist/lib/libcrypto.a(threads_pthread.o): In function `CRYPTO_THREAD_lock_free':
threads_pthread.c:(.text+0xca): undefined reference to `pthread_rwlock_destroy'
/home/cretz/work/bine/gopath/src/github.com/cretz/tor-static/tor/../openssl/dist/lib/libcrypto.a(threads_pthread.o): In function `CRYPTO_THREAD_run_once':
threads_pthread.c:(.text+0xf5): undefined reference to `pthread_once'
/home/cretz/work/bine/gopath/src/github.com/cretz/tor-static/tor/../openssl/dist/lib/libcrypto.a(threads_pthread.o): In function `CRYPTO_THREAD_init_local':
threads_pthread.c:(.text+0x115): undefined reference to `pthread_key_create'
/home/cretz/work/bine/gopath/src/github.com/cretz/tor-static/tor/../openssl/dist/lib/libcrypto.a(threads_pthread.o): In function `CRYPTO_THREAD_set_local':
threads_pthread.c:(.text+0x147): undefined reference to `pthread_setspecific'
/home/cretz/work/bine/gopath/src/github.com/cretz/tor-static/tor/../openssl/dist/lib/libcrypto.a(threads_pthread.o): In function `CRYPTO_THREAD_cleanup_local':
threads_pthread.c:(.text+0x167): undefined reference to `pthread_key_delete'
/home/cretz/work/bine/gopath/src/github.com/cretz/tor-static/tor/../openssl/dist/lib/libcrypto.a(threads_pthread.o): In function `CRYPTO_THREAD_get_local':
threads_pthread.c:(.text+0x133): undefined reference to `pthread_getspecific'
/home/cretz/work/bine/gopath/src/github.com/cretz/tor-static/tor/../openssl/dist/lib/libcrypto.a(threads_pthread.o): In function `CRYPTO_THREAD_get_current_id':
threads_pthread.c:(.text+0x181): undefined reference to `pthread_self'
/usr/lib/gcc/x86_64-linux-gnu/5/libgcc_eh.a(unwind-dw2.o): In function `uw_init_context_1':
(.text+0x1e0d): undefined reference to `pthread_once'
collect2: error: ld returned 1 exit status

And also:

configure:9732: gcc -o conftest -g -O2 -static   conftest.c -lpthread -ldl  -lssl -lcrypto   >&5
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_globallookup':
(.text+0x11): undefined reference to `dlopen'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_globallookup':
(.text+0x24): undefined reference to `dlsym'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_globallookup':
(.text+0x2f): undefined reference to `dlclose'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_bind_func':
(.text+0x334): undefined reference to `dlsym'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_bind_func':
(.text+0x3db): undefined reference to `dlerror'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_bind_var':
(.text+0x454): undefined reference to `dlsym'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_bind_var':
(.text+0x4fb): undefined reference to `dlerror'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_load':
(.text+0x569): undefined reference to `dlopen'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_load':
(.text+0x5cb): undefined reference to `dlclose'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_load':
(.text+0x603): undefined reference to `dlerror'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_pathbyaddr':
(.text+0x69f): undefined reference to `dladdr'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_pathbyaddr':
(.text+0x709): undefined reference to `dlerror'
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/libcrypto.a(dso_dlfcn.o): In function `dlfcn_unload':
(.text+0x762): undefined reference to `dlclose'
collect2: error: ld returned 1 exit status

This is happening because the gcc call is putting -lssl and -lcrypto after -lpthread and -ldl instead of before it. This apparently has been happening a long time (see #12720) and I can't find any recent blame to cause this. I have also confirmed this is happening in Windows using MinGW on static builds too.

Please adjust TOR_SEARCH_LIBRARY or whatever is needed to make sure the -lssl and -lcrypto appear first on these checks. In the meantime, devs can solve this by setting the LIBS env var to "-lssl -lcrypto -lcrypt32 -lgdi32 -lws2_32" at least on Windows and presumably "-lssl -lcrypto -lpthread -ldl" on Linux (running into #6623 on Linux, so unsure).

Child Tickets

Attachments (1)

0001-TOR_SEARCH_LIBRARY-Prepend-library-to-LIBS-instead-o.patch (1.2 KB) - added by str4d 2 weeks ago.

Download all attachments as: .zip

Change History (14)

comment:1 Changed 13 months ago by teor

Keywords: static 029-backport 032-backport 033-backport 034-backport added
Milestone: Tor: 0.3.5.x-final
Parent ID: #6623

I am not sure whether to put this fix in 0.3.5 or 0.3.6, but it would be nice to have a working static binary in our LTS release.
It might also be good to backport these fixes, if they aren't too big.

comment:2 Changed 13 months ago by cretz

Just to clarify for here and #6623, static compilation works perfectly fine with OpenSSL 1.0.2 on Windows, Linux, and macOS. It's just 1.1.0 that causes an issue. My script visible at https://github.com/cretz/tor-static/tree/tor-0.3.5.x.

comment:3 Changed 11 months ago by teor

Keywords: 032-unreached-backport added; 032-backport removed

0.3.2 is end of life, so 032-backport is now 032-unreached-backport.

comment:4 Changed 8 months ago by nickm

How are more recent versions of openssl looking?

comment:5 Changed 8 months ago by teor

Milestone: Tor: 0.3.5.x-finalTor: unspecified

There is no code in this bug.

comment:6 Changed 8 months ago by teor

Keywords: 033-backport removed

These open, non-merge_ready tickets can not get backported to 0.3.3, because 0.3.3 is now unsupported.

comment:7 Changed 8 months ago by teor

Keywords: 033-backport-unreached added

Hmm, I guess they should still get 033-backport-unreached

comment:8 Changed 4 months ago by nickm

Keywords: 034-backport removed

Removing 034-backport from all open tickets: 034 has reached EOL.

comment:9 Changed 2 months ago by teor

Keywords: 033-unreached-backport added; 033-backport-unreached removed

Fix 033-unreached-backport spelling.

comment:10 Changed 2 weeks ago by str4d

I encountered this problem with OpenSSL 1.1.1a. The problem here is that -lpthread appears before -lcrypto. This is caused by a bug in TOR_SEARCH_LIBRARY (in acinclude.m4) where the candidate library flags are appended to LIBS instead of prepended. (EDIT: I see that this was mentioned at the bottom of the OP). See the above patch for the fix.

With this patch applied, I'm running into a subsequent configuration error caused by a segfault that is likely related to the fix for #25353.

configure:9701: Now, we'll look for OpenSSL >= 1.0.1
configure:9722: checking for openssl directory
configure:9777: gcc -m64 -o conftest -pipe -O1     -static -I/path/to/include -I/path/to/include     -L/path/to/lib -L/path/to/lib     conftest.c -lssl -lcrypto   -lpthread -ldl  >&5
/path/to/lib/libcrypto.a(b_addr.o): In function `BIO_lookup_ex':
b_addr.c:(.text+0xc73): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/path/to/lib/libcrypto.a(b_sock.o): In function `BIO_gethostbyname':
b_sock.c:(.text+0x69): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
configure:9777: $? = 0
configure:9800: gcc -m64 -c -pipe -O1     -static -I/path/to/include -I/path/to/include     conftest.c >&5
configure:9800: $? = 0
configure:9893: result: /path/to
configure:9934: checking whether we need extra options to link openssl
configure:9988: gcc -m64 -o conftest -pipe -O1     -static -I/path/to/include -I/path/to/include     -L/path/to/lib -L/path/to/lib     conftest.c -lssl -lcrypto   -lpthread -ldl  >&5
/path/to/lib/libcrypto.a(b_addr.o): In function `BIO_lookup_ex':
b_addr.c:(.text+0xc73): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/path/to/lib/libcrypto.a(b_sock.o): In function `BIO_gethostbyname':
b_sock.c:(.text+0x69): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
configure:9988: $? = 0
configure:9988: ./conftest
./configure: line 1962: 11810 Segmentation fault      (core dumped) ./conftest$ac_exeext
configure:9988: $? = 139
configure: program exited with status 139
configure: failed program was:
| /* confdefs.h */
| #define PACKAGE_NAME "tor"
| #define PACKAGE_TARNAME "tor"
| #define PACKAGE_VERSION "0.4.2.1-alpha-dev"
| #define PACKAGE_STRING "tor 0.4.2.1-alpha-dev"
| #define PACKAGE_BUGREPORT ""
| #define PACKAGE_URL ""
| #define APPROX_RELEASE_DATE "2019-09-17"
| #define PACKAGE "tor"
| #define VERSION "0.4.2.1-alpha-dev"
| #define STDC_HEADERS 1
| #define HAVE_SYS_TYPES_H 1
| #define HAVE_SYS_STAT_H 1
| #define HAVE_STDLIB_H 1
| #define HAVE_STRING_H 1
| #define HAVE_MEMORY_H 1
| #define HAVE_STRINGS_H 1
| #define HAVE_INTTYPES_H 1
| #define HAVE_STDINT_H 1
| #define HAVE_UNISTD_H 1
| #define __EXTENSIONS__ 1
| #define _ALL_SOURCE 1
| #define _GNU_SOURCE 1
| #define _POSIX_PTHREAD_SEMANTICS 1
| #define _TANDEM_SOURCE 1
| #define ENABLE_OPENSSL 1
| #define ENABLE_ZSTD_ADVANCED_APIS 1
| #define HAVE_MODULE_DIRAUTH 1
| #define FLEXIBLE_ARRAY_MEMBER /**/
| #define HAVE_ACCEPT4 1
| #define HAVE_BACKTRACE 1
| #define HAVE_BACKTRACE_SYMBOLS_FD 1
| #define HAVE_EVENTFD 1
| #define HAVE_EXPLICIT_BZERO 1
| #define HAVE_FLOCK 1
| #define HAVE_FTIME 1
| #define HAVE_GET_CURRENT_DIR_NAME 1
| #define HAVE_GETADDRINFO 1
| #define HAVE_GETDELIM 1
| #define HAVE_GETIFADDRS 1
| #define HAVE_GETLINE 1
| #define HAVE_GETPASS 1
| #define HAVE_GETRLIMIT 1
| #define HAVE_GETTIMEOFDAY 1
| #define HAVE_GMTIME_R 1
| #define HAVE_GNU_GET_LIBC_VERSION 1
| #define HAVE_INET_ATON 1
| #define HAVE_IOCTL 1
| #define HAVE_LOCALTIME_R 1
| #define HAVE_MADVISE 1
| #define HAVE_MEMMEM 1
| #define HAVE_MMAP 1
| #define HAVE_PIPE 1
| #define HAVE_PIPE2 1
| #define HAVE_PRCTL 1
| #define HAVE_SIGACTION 1
| #define HAVE_SOCKETPAIR 1
| #define HAVE_STATVFS 1
| #define HAVE_STRNCASECMP 1
| #define HAVE_STRCASECMP 1
| #define HAVE_STRNLEN 1
| #define HAVE_STRPTIME 1
| #define HAVE_STRTOK_R 1
| #define HAVE_STRTOULL 1
| #define HAVE_SYSCONF 1
| #define HAVE_SYSCTL 1
| #define HAVE_TRUNCATE 1
| #define HAVE_UNAME 1
| #define HAVE_USLEEP 1
| #define HAVE_VASPRINTF 1
| #define HAVE_CLOCK_GETTIME 1
| #define HAVE_GETENTROPY 1
| #define HAVE_PTHREAD_H 1
| #define HAVE_PTHREAD_CREATE 1
| #define HAVE_PTHREAD_CONDATTR_SETCLOCK 1
| #define HAVE_EVENT2_EVENT_H 1
| #define HAVE_EVENT2_DNS_H 1
| #define HAVE_EVENT2_BUFFEREVENT_SSL_H 1
| /* end confdefs.h.  */
| struct ssl_cipher_st;
|      unsigned SSL_CIPHER_get_id(const struct ssl_cipher_st *);
|      char *getenv(const char *);
| int
| main ()
| {
|                         if (getenv("THIS_SHOULDNT_BE_SET_X201803")) SSL_CIPHER_get_id((void *)0);
|   ;
|   return 0;
| }
Last edited 2 weeks ago by str4d (previous) (diff)

comment:11 Changed 2 weeks ago by nickm

Keywords: 042-can? added
Milestone: Tor: unspecifiedTor: 0.4.2.x-final

comment:12 Changed 2 weeks ago by str4d

Compiling and running the above failed program in GDB, I get:

$ gcc -m64 -o conftest -pipe -O1     -static -I/path/to/include -L/path/to/lib     conftest.c -lssl -lcrypto   -lpthread -ldl
/path/to/lib/libcrypto.a(b_addr.o): In function `BIO_lookup_ex':
b_addr.c:(.text+0xc73): warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/path/to/lib/libcrypto.a(b_sock.o): In function `BIO_gethostbyname':
b_sock.c:(.text+0x69): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
$ gdb conftest
GNU gdb (Ubuntu 8.1-0ubuntu3.1) 8.1.0.20180409-git
Copyright (C) 2018 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-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...

warning: ~/.gdbinit.local-pre: No such file or directory
/home/str4d/.gdbinit:80: Error in sourced command file:
t SW:2600: Error in sourced command file:
Undefined command: "SW".  Try "help".
Reading symbols from conftest...done.
gdb$ r
Starting program: /home/str4d/dev/git/tor/tmp/conftest 

Program received signal SIGSEGV, Segmentation fault.
0x0000000000000000 in ?? ()
gdb$ bt
#0  0x0000000000000000 in ?? ()
#1  0x00000000004f9e55 in __register_frame_info_bases.part.6 ()
#2  0x0000000000400c5d in frame_dummy ()
#3  0x0000000000000001 in ?? ()
#4  0x00000000004fb0cc in __libc_csu_init ()
#5  0x00000000004fa897 in __libc_start_main ()
#6  0x0000000000400b7a in _start ()

If I remove the -static flag, the program successfully runs, and when doing the equivalent for Tor (--enable-static-openssl etc. instead of --enable-static-tor), ./configure succeeds.

Last edited 2 weeks ago by str4d (previous) (diff)

comment:13 Changed 2 weeks ago by teor

If we want to support building a static Tor, we should get static builds working, and then add CI for it.

Note: See TracTickets for help on using tickets.