After base r320472 net/torsocks started to crash when torifying www/w3m-img but not other apps. $ pkg install gdb torsocks w3m-img ca_root_nss $ env -i LD_PRELOAD=/usr/local/lib/torsocks/libtorsocks.so \ /usr/local/bin/gdb /usr/local/bin/w3m https://freebsd.org [...] Program received signal SIGSEGV, Segmentation fault. __pthread_cleanup_push_imp (routine=0x80208ff30 <__stdio_cancel_cleanup>, arg=0x0, info=0x7fffffffd7b0) at /usr/src/lib/libthr/thread/thr_clean.c:60 60 newbuf->prev = curthread->cleanup; (gdb) bt f #0 __pthread_cleanup_push_imp (routine=0x80208ff30 <__stdio_cancel_cleanup>, arg=0x0, info=0x7fffffffd7b0) at /usr/src/lib/libthr/thread/thr_clean.c:60 curthread = 0x0 #1 0x000000080207275e in fgets (buf=0x7fffffffd850 "i\a", n=1024, fp=0x8022f2020) at /usr/src/lib/libc/stdio/fgets.c:59 __cleanup_info__ = {pthread_cleanup_pad = {140737488346208, 34393882416, 0, 18446735337746071552, 18446741944445842436, 20, 140737488345168, 1024}} s = 0x7fffffffd850 "i\a" p = <optimized out> len = <optimized out> t = <optimized out> ret = <optimized out> #2 0x00000008008f8fa2 in parse_config_file (fp=0x8022f2020, config=0x800b04960 <tsocks_config>) at config-file.c:209 ret = -1 line = "i\a\000\000\000\000\000\000X\332\377\377\377\177\000\000\000\332\377\377\377\177", '\000' <repeats 22 times>, "\b\000\000\000X\333\377\377\377\177\000\000T\213\362\001\b\000\000\000\276ff\000\000\000\000\000\366\337\364\016\377\177\000\000\300\346n\000\b\000\000\000\001\000\000\000\b\000\000\000\000do\000\b\000\000\000P\346\361\001\b\000\000\000\003\000\000\000\377\177\000\000\000\331\377\377\377\177\000\000\000\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000\016\000\000\000\000\000\000\000X\332\377\377\377\177\000\000@\332\377\377\377\177\000\000\317\364l\000\b\000\000\000\000\360n\000\b\000\000\000\000\364n\000\b\000\000\000\000\370n\000\b\000\000\000\000"... #3 0x00000008008f8a92 in config_file_read ( filename=0x800900e38 "/usr/local/etc/tor/torsocks.conf", config=0x800b04960 <tsocks_config>) at config-file.c:567 ret = 8 fp = 0x8022f2020 #4 0x00000008008f267b in init_config () at torsocks.c:163 ret = 0 filename = 0x0 #5 0x00000008008f20f6 in tsocks_init () at torsocks.c:328 ret = 8 #6 0x00000008008fa285 in tsocks_once (o=0x800b047c8 <init_once>, init_routine=0x8008f20b0 <tsocks_init>) at compat.c:94 No locals. #7 0x00000008008f2089 in tsocks_initialize () at torsocks.c:702 No locals. #8 0x00000008008feea2 in __do_global_ctors_aux () from /usr/local/lib/torsocks/libtorsocks.so No symbol table info available. #9 0x00000008008f0c96 in _init () from /usr/local/lib/torsocks/libtorsocks.so No symbol table info available. #10 0x00007fffffffe210 in ?? () No symbol table info available. #11 0x00000008006ce8a8 in objlist_call_init (list=<optimized out>, lockstate=<optimized out>) at rtld.c:2633 obj = <optimized out> elm = 0x800b04210 <__CTOR_LIST__> init_addr = <optimized out> saved_msg = <optimized out> #12 0x00000008006cd9ec in _rtld (sp=0x7fffffffed48, exit_proc=<optimized out>, objp=<optimized out>) at rtld.c:759 aux_info = {0x0, 0x0, 0x0, 0x7fffffffed70, 0x7fffffffed80, 0x7fffffffed90, 0x7fffffffeda0, 0x7fffffffedd0, 0x7fffffffedb0, 0x7fffffffedc0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x7fffffffede0, 0x7fffffffee00, 0x7fffffffee10, 0x7fffffffedf0, 0x7fffffffee20, 0x7fffffffee30, 0x7fffffffee40, 0x7fffffffee50, 0x7fffffffee60} buf = '\000' <repeats 1023 times> mib = {0, 0} argcp = <optimized out> argc = 7270400 argv0 = <optimized out> len = 0 fd = <optimized out> phdr = <optimized out> rtld_argc = <optimized out> search_in_path = <optimized out> st = {st_dev = 0, st_ino = 0, st_nlink = 0, st_mode = 0, st_padding0 = 0, st_uid = 0, st_gid = 0, st_padding1 = 0, st_rdev = 0, st_atim = {tv_sec = 0, tv_nsec = 0}, st_mtim = {tv_sec = 0, tv_nsec = 0}, st_ctim = {tv_sec = 0, tv_nsec = 0}, st_birthtim = { tv_sec = 0, tv_nsec = 0}, st_size = 0, st_blocks = 0, st_blksize = 0, st_flags = 0, st_gen = 0, st_spare = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}} dir_enable = <error reading variable dir_enable (Cannot access memory at address 0x1)> library_path_rpath = <optimized out> phnum = <optimized out> kexecpath = <optimized out> obj = <optimized out> last_interposer = <optimized out> entry = <optimized out> aux = <optimized out> preload_tail = <optimized out> initlist = {stqh_first = 0x8006ed6a0, stqh_last = 0x8006ed9e0} lockstate = {lockstate = 2, env = {{_sjb = {0 <repeats 12 times>}}}} #13 0x00000008006cb669 in .rtld_start () at /usr/src/libexec/rtld-elf/amd64/rtld_start.S:39 No locals. #14 0x0000000000000000 in ?? () No symbol table info available.
Adding /lib/libthr.so.3 to LD_PRELOAD makes the crash go away. w3m is already linked against libthr.so.3 but torsocks isn't, so FLOCKFILE_CANCELSAFE() probably ends up using pthread stubs.
(In reply to Jan Beich from comment #1) No, the normal libthr clean code is bound, and this is the problem since libthr is not yet initialized due to LD_PRELOAD causing the libtorsocks.so to stay out of normal initialization order. Try the patch, only libthr.so needs to be rebuild.
Created attachment 183939 [details] Initialize libthr if cleanup handler is called.
Comment on attachment 183939 [details] Initialize libthr if cleanup handler is called. Assertion failed: (!ret), function tsocks_mutex_unlock, file compat.c, line 72. Program received signal SIGABRT, Aborted. thr_kill () at thr_kill.S:3 3 RSYSCALL(thr_kill) (gdb) bt #0 thr_kill () at thr_kill.S:3 #1 0x0000000801ff7ff4 in __raise (s=6) at /usr/src/lib/libc/gen/raise.c:52 #2 0x0000000801ff7f69 in abort () at /usr/src/lib/libc/stdlib/abort.c:65 #3 0x000000080207b1f1 in __assert (func=<optimized out>, file=<optimized out>, line=<optimized out>, failedexpr=<optimized out>) at /usr/src/lib/libc/gen/assert.c:51 #4 0x00000008008fa1c3 in tsocks_mutex_unlock (m=0x800b047d0 <init_once+8>) at compat.c:72 #5 0x00000008008fa2a0 in tsocks_once (o=0x800b047c8 <init_once>, init_routine=0x8008f20b0 <tsocks_init>) at compat.c:97 #6 0x00000008008f2089 in tsocks_initialize () at torsocks.c:702 #7 0x00000008008feea2 in __do_global_ctors_aux () from /usr/local/lib/torsocks/libtorsocks.so #8 0x00000008008f0c96 in _init () from /usr/local/lib/torsocks/libtorsocks.so #9 0x00007fffffffe220 in ?? () #10 0x00000008006ce8a8 in objlist_call_init (list=<optimized out>, lockstate=<optimized out>) at rtld.c:2633 #11 0x00000008006cd9ec in _rtld (sp=0x7fffffffed50, exit_proc=<optimized out>, objp=<optimized out>) at rtld.c:759 #12 0x00000008006cb669 in .rtld_start () at /usr/src/libexec/rtld-elf/amd64/rtld_start.S:39 #13 0x0000000000000000 in ?? () (gdb) f 4 #4 0x00000008008fa1c3 in tsocks_mutex_unlock (m=0x800b047d0 <init_once+8>) at compat.c:72 72 assert(!ret); (gdb) l 67 ret = pthread_mutex_unlock(&m->mutex); 68 /* 69 * Unable to unlock the mutex could lead to undefined behavior and potential 70 * security issues. Stop everything so torsocks can't continue. 71 */ 72 assert(!ret); 73 } 74 75 /* 76 * Call the given routine once, and only once. tsocks_once returning
Created attachment 183949 [details] Try harder to call libc stubs for cleanup push/pop_imp, if libthr still not yet initialized.
Comment on attachment 183949 [details] Try harder to call libc stubs for cleanup push/pop_imp, if libthr still not yet initialized. Thank you. With this version torsocks no longer crashes here.
A commit references this bug: Author: kib Date: Fri Jun 30 20:27:52 UTC 2017 New revision: 320509 URL: https://svnweb.freebsd.org/changeset/base/320509 Log: In the stdio cleanup push and pop wrappers, always call libc stubs for __pthread_cleanup_push/pop_imp instead of symbols also exported from libthr. This prevents calls into libthr if libthr is not yet initialized. The situation occurs e.g. when an LD_PRELOADed object is not linked against libthr, but the main binary is. Reported and tested by: jbeich PR: 220381 Discussed with: vangyzen Sponsored by: The FreeBSD Foundation MFC after: 13 days Changes: head/lib/libc/include/libc_private.h head/lib/libc/stdio/local.h
It looks like no action is required in the torsocks port itself.
Looks like this has been resolved, closing PR.