Torsocks issueshttps://gitlab.torproject.org/tpo/core/torsocks/-/issues2021-11-15T16:43:09Zhttps://gitlab.torproject.org/tpo/core/torsocks/-/issues/24116Torsocks deadlocks every Rust program2021-11-15T16:43:09ZTracTorsocks deadlocks every Rust programAny Rust program that is run with torsocks will deadlock. This has nothing to do with networking, even the program 'fn main() { }' compiled with a recent rustc will deadlock when run as 'torsocks ./rust_torsocks'.
This is a backtrace I ...Any Rust program that is run with torsocks will deadlock. This has nothing to do with networking, even the program 'fn main() { }' compiled with a recent rustc will deadlock when run as 'torsocks ./rust_torsocks'.
This is a backtrace I got when attaching to the deadlocked process:
```
#0 0xb7713cf9 in __kernel_vsyscall ()
#1 0xb76b9d92 in __lll_lock_wait ()
at ../sysdeps/unix/sysv/linux/i386/lowlevellock.S:144
#2 0xb76b38de in __GI___pthread_mutex_lock (mutex=0xb770d024)
at ../nptl/pthread_mutex_[lock.c:80 lock.c:80]
#3 0xb77001ed in tsocks_mutex_lock ()
from /usr/lib/i386-linux-gnu/torsocks/libtorsocks.so
#4 0xb7700334 in tsocks_once ()
from /usr/lib/i386-linux-gnu/torsocks/libtorsocks.so
#5 0xb76fa25e in tsocks_initialize ()
from /usr/lib/i386-linux-gnu/torsocks/libtorsocks.so
#6 0xb76fd02d in syscall ()
from /usr/lib/i386-linux-gnu/torsocks/libtorsocks.so
#7 0x004a5049 in os_overcommits_proc ()
at /checkout/src/liballoc_jemalloc/../jemalloc/src/pages.c:252
#8 je_pages_boot ()
at /checkout/src/liballoc_jemalloc/../jemalloc/src/pages.c:297
#9 0x004745dd in malloc_init_hard_a0_locked ()
at /checkout/src/liballoc_jemalloc/../jemalloc/src/jemalloc.c:1366
#10 0x00474768 in malloc_init_hard ()
at /checkout/src/liballoc_jemalloc/../jemalloc/src/jemalloc.c:1493
#11 0x00489b95 in malloc_init ()
at /checkout/src/liballoc_jemalloc/../jemalloc/src/jemalloc.c:317
#12 ialloc_body (slow_path=true, usize=<synthetic pointer>,
tsdn=<synthetic pointer>, zero=true, size=20)at /checkout/src/liballoc_jemalloc/../jemalloc/src/jemalloc.c:1583
#13 calloc (num=1, size=20)
at /checkout/src/liballoc_jemalloc/../jemalloc/src/jemalloc.c:1824
#14 0xb76d23ec in _dlerror_run (
operate=operate@entry=0xb76d1b80 <dlopen_doit>, args=args@entry=0xbfb8cd10)
#15 0xb76d1c9e in __dlopen (file=0xb7703345 "libc.so.6", mode=1) at dlopen.c:87
#16 0xb76fa44f in ?? () from /usr/lib/i386-linux-gnu/torsocks/libtorsocks.so
#17 0xb7700352 in tsocks_once ()__
from /usr/lib/i386-linux-gnu/torsocks/libtorsocks.so
#18 0xb76fa25e in tsocks_initialize ()
from /usr/lib/i386-linux-gnu/torsocks/libtorsocks.so
#19 0xb7724c65 in call_init (l=<optimized out>, argc=argc@entry=1,
argv=argv@entry=0xbfb8ce74, env=0xbfb8ce7c) at dl-init.c:72
#20 0xb7724d8e in call_init (env=0xbfb8ce7c, argv=0xbfb8ce74, argc=1,
l=<optimized out>) at dl-init.c:30
#21 _dl_init (main_map=<optimized out>, argc=1, argv=0xbfb8ce74,
env=0xbfb8ce7c) at dl-init.c:120
#22 0xb7715a5f in _dl_start_user () from /lib/ld-linux.so.2
```
It looks like tsocks_initialize() is called when libtorsocks is loaded, it calls tsocks_once() which locks a mutex and then calls dlopen() to get the libc symbols, dlopen() tries to allocate some memory which leads jemalloc (the default allocator for Rust programs) to try to call syscall() (it wants to open a proc file to see if the system overcommits memory or not), which is intercepted by libtorsocks, which leads to another call to tsocks_initialize()... and since the mutex is already locked, it deadlocks.
One way to fix this might be to just let through any syscall() calls that happen during bootstrapping, but i don't know the torsocks code well enough to know if this could cause any dangerous leaks.
**Trac**:
**Username**: larsl