Bug 220381 - net/torsocks: sometimes crashes on 12.0-CURRENT
Summary: net/torsocks: sometimes crashes on 12.0-CURRENT
Status: Closed FIXED
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-ports-bugs (Nobody)
URL:
Keywords: crash, needs-qa
Depends on:
Blocks:
 
Reported: 2017-06-30 12:18 UTC by Jan Beich
Modified: 2017-07-05 19:39 UTC (History)
4 users (show)

See Also:
bugzilla: maintainer-feedback? (yuri)


Attachments
Initialize libthr if cleanup handler is called. (565 bytes, patch)
2017-06-30 12:52 UTC, Konstantin Belousov
no flags Details | Diff
Try harder to call libc stubs for cleanup push/pop_imp, if libthr still not yet initialized. (1.46 KB, patch)
2017-06-30 17:38 UTC, Konstantin Belousov
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jan Beich freebsd_committer freebsd_triage 2017-06-30 12:18:31 UTC
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.
Comment 1 Jan Beich freebsd_committer freebsd_triage 2017-06-30 12:36:48 UTC
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.
Comment 2 Konstantin Belousov freebsd_committer freebsd_triage 2017-06-30 12:51:49 UTC
(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.
Comment 3 Konstantin Belousov freebsd_committer freebsd_triage 2017-06-30 12:52:31 UTC
Created attachment 183939 [details]
Initialize libthr if cleanup handler is called.
Comment 4 Jan Beich freebsd_committer freebsd_triage 2017-06-30 13:09:45 UTC
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
Comment 5 Konstantin Belousov freebsd_committer freebsd_triage 2017-06-30 17:38:31 UTC
Created attachment 183949 [details]
Try harder to call libc stubs for cleanup push/pop_imp, if libthr still not yet initialized.
Comment 6 Jan Beich freebsd_committer freebsd_triage 2017-06-30 18:39:43 UTC
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.
Comment 7 commit-hook freebsd_committer freebsd_triage 2017-06-30 20:28:01 UTC
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
Comment 8 Yuri Victorovich freebsd_committer freebsd_triage 2017-06-30 21:49:51 UTC
It looks like no action is required in the torsocks port itself.
Comment 9 Richard Gallamore freebsd_committer freebsd_triage 2017-07-05 19:39:51 UTC
Looks like this has been resolved, closing PR.