Torsocks does not work with the Scudo memory allocator
Hey, I tried switching to the scudo memory allocator (it's a hardened malloc implementation from the LLVM project that's now used as the default malloc on Android) on my system and torsocks no longer works and attempting to run any program through it just freezes.
I did some debugging with strace and noticed it was getting stuck on a futex() call.
strace -e futex torsocks curl 1.1.1.1
futex(0x6f36109e488c, FUTEX_WAKE_PRIVATE, 2147483647) = 0
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=165508, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=165509, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
futex(0x6e8496180684, FUTEX_WAIT_PRIVATE, 1, NULL
With some further printf debugging, I narrowed it down to the following code
in src/lib/torsocks.c
, specifically the dlopen() call:
static void init_libc_symbols(void)
{
int ret;
void *libc_ptr;
dlerror();
libc_ptr = dlopen(LIBC_NAME, RTLD_LAZY);
Then I wrote a simple test case to try to reproduce the issue:
#include <dlfcn.h>
int main() {
char* libc_ptr = dlopen("libc.so.6", RTLD_LAZY);
return 0;
}
It did not freeze like torsocks did, but it did get me a more complete stack trace out of strace:
strace -e futex -k ./a.out
futex(0x638a2a903684, FUTEX_WAKE_PRIVATE, 2147483647) = 0
> /nix/store/8bmp6r3a0xfha3wj36phlc47clh9w81l-glibc-2.35-224/lib/libc.so.6(__pthread_once_slow+0x110) [0x8e0a0]
> /nix/store/yrlxfw3zh4lhsvmx2xwm6d0damhs6qwl-malloc-provider-scudo/lib/libclang_rt.scudo-x86_64.so(_ZN7__scudo10initThreadEb+0x1e) [0xd29e]
> /nix/store/yrlxfw3zh4lhsvmx2xwm6d0damhs6qwl-malloc-provider-scudo/lib/libclang_rt.scudo-x86_64.so(_ZN7__scudo9Allocator8allocateEmmNS_9AllocTypeEb+0x68c) [0xa04c]
> /nix/store/yrlxfw3zh4lhsvmx2xwm6d0damhs6qwl-malloc-provider-scudo/lib/libclang_rt.scudo-x86_64.so(_ZN7__scudo13scudoAllocateEmmNS_9AllocTypeE+0x2e) [0x659e]
> /nix/store/wvm2hvqdbbsp1f11463mrw8nyv678ipm-gcc-12.2.0-lib/lib/libstdc++.so.6.0.30(_GLOBAL__sub_I_eh_alloc.cc+0x3a) [0xb18aa]
> /nix/store/8bmp6r3a0xfha3wj36phlc47clh9w81l-glibc-2.35-224/lib/ld-linux-x86-64.so.2(call_init+0xbe) [0x5e1e]
> /nix/store/8bmp6r3a0xfha3wj36phlc47clh9w81l-glibc-2.35-224/lib/ld-linux-x86-64.so.2(_dl_init+0x7c) [0x5f0c]
> /nix/store/8bmp6r3a0xfha3wj36phlc47clh9w81l-glibc-2.35-224/lib/ld-linux-x86-64.so.2(_dl_help+0x49a) [0x1d3da]
+++ exited with 0 +++
I also tried disabling scudo system-wide and just using LD_PRELOAD for both torsocks and scudo:
LD_PRELOAD="result/lib/torsocks/libtorsocks.so /nix/store/yrlxfw3zh4lhsvmx2xwm6d0damhs6qwl-malloc-provider-scudo/lib/libclang_rt.scudo-x86_64.so" curl 1.1.1.1
LD_PRELOAD="/nix/store/yrlxfw3zh4lhsvmx2xwm6d0damhs6qwl-malloc-provider-scudo/lib/libclang_rt.scudo-x86_64.so result/lib/torsocks/libtorsocks.so" curl 1.1.1.1
The order the libraries get LD_PRELOADed does not seem to matter, it still freezes the same way in both cases.
I know running scudo on a desktop Linux system is an uncommon use case and this may actually be a scudo bug, but I'm reporting this in the hopes that somebody more knowledgeable might look into this and get it fixed.
I have also tested it with GrapheneOS's hardened-malloc and it does not have the same problem. It seems unique to scudo.
Proxychains and proxychains-ng both work with scudo.