rofl0r / microsocks

tiny, portable SOCKS5 server with very moderate resource usage
Other
1.35k stars 254 forks source link

segmentation fault on alpine & docker #73

Closed tbobbera closed 2 weeks ago

tbobbera commented 2 weeks ago

I was trying to build and run microsocks in a Docker container and noticed that the server will crash when it attempts to make a DNS resolve

You should be able to replicate in a Docker container like this:

FROM alpine:latest
# Get GCC and git
RUN apk add git build-base make --no-cache --update
# Get microsocks
RUN git clone https://github.com/rofl0r/microsocks msocks
# Make
WORKDIR msocks
RUN make
RUN apk add bash procps curl vim gdb python3 valgrind --no-cache --update --upgrade grep

ENTRYPOINT ["sleep", "infinity"]

And then spawning a shell and running microsocks with gdb to see the seg fault

Running microsocks itself is OK, and it can handle requests to 1.1.1.1 etc, but as soon as I hit a domain name with curl it'll seg fault

I rebuilt with debug flags and ran with gdb and got this:

Reading symbols from ./microsocks...
(gdb) r
Starting program: /msocks/microsocks
[New LWP 114]

Thread 2 "microsocks" received signal SIGSEGV, Segmentation fault.
[Switching to LWP 114]
0x00007ffff7f9a0be in name_from_dns (buf=buf@entry=0x7ffff7f54e20, canon=canon@entry=0x7ffff7f54d20 "ipinfo.io", name=name@entry=0x7ffff7f55470 "ipinfo.io", family=family@entry=0,
    conf=conf@entry=0x7ffff7f54b10) at src/network/lookup_name.c:144
warning: 144    src/network/lookup_name.c: No such file or directory
(gdb) bt
#0  0x00007ffff7f9a0be in name_from_dns (buf=buf@entry=0x7ffff7f54e20, canon=canon@entry=0x7ffff7f54d20 "ipinfo.io", name=name@entry=0x7ffff7f55470 "ipinfo.io", family=family@entry=0,
    conf=conf@entry=0x7ffff7f54b10) at src/network/lookup_name.c:144
#1  0x00007ffff7f9aba7 in name_from_dns_search (family=0, name=0x7ffff7f55470 "ipinfo.io", canon=0x7ffff7f54d20 "ipinfo.io", buf=0x7ffff7f54e20) at src/network/lookup_name.c:231
#2  __lookup_name (buf=buf@entry=0x7ffff7f54e20, canon=canon@entry=0x7ffff7f54d20 "ipinfo.io", name=name@entry=0x7ffff7f55470 "ipinfo.io", family=<optimized out>, family@entry=0,
    flags=<optimized out>, flags@entry=1) at src/network/lookup_name.c:334
#3  0x00007ffff7f97a57 in getaddrinfo (host=0x7ffff7f55470 "ipinfo.io", serv=<optimized out>, hint=<optimized out>, res=0x7ffff7f55448) at src/network/getaddrinfo.c:94
#4  0x0000555555556839 in resolve ()
#5  0x0000555555555690 in connect_socks_target ()
#6  0x000055555555618a in clientthread ()
#7  0x00007ffff7fb822e in start (p=0x7ffff7f55b00) at src/thread/pthread_create.c:207
#8  0x00007ffff7fba82f in __clone () at src/thread/x86_64/clone.s:22
Backtrace stopped: frame did not save the PC

This seems to happen on:

I can get it working with alpine:3.14.3 instead of alpine:latest which is likely the version I used 3 years ago when I first made my image That uses musl-1.2.2: musl-1.2.2-r5 x86_64 {musl} (MIT) [installed]

The issue happens here: https://github.com/rofl0r/microsocks/blob/655c53d27df0bd69e0ecfa8309ce2940797f3362/server.c#L14 -- I've tried dumping variables etc and everything seems OK based on what getaddrinfo() expects.

Oddly running python in the container and using getaddrinfo() with similar arguments works fine...

I'm not a C dev so I'm not sure what else to do other than use another distro/Docker base image to run microsocks in. I cannot tell if this is a musl issue or not.

I wonder if anybody else is facing this issue or has some ideas on how to solve this cause I'm curious why this is happening.

rofl0r commented 2 weeks ago

seems most likely related to thread stack size. the DNS resolver in musl 1.2.4 has some new code for TCP based DNS lookup, so maybe it requires more stack than previous versions.

try to change line 50 in socksrv.c from

#define THREAD_STACK_SIZE MAX(8*1024, PTHREAD_STACK_MIN)

to

#define THREAD_STACK_SIZE MAX(12*1024, PTHREAD_STACK_MIN)
itsjfx commented 2 weeks ago

thanks for the quick response

12 didn't work but after incrementing it appears to start working at around 16

#define THREAD_STACK_SIZE MAX(16*1024, PTHREAD_STACK_MIN)
rofl0r commented 2 weeks ago

cool. please notify me when you're reasonably sure that with 16kb there are no issues anymore (maybe test with some extremely long dns names).

itsjfx commented 2 weeks ago

On 16kb haven't been able to make it seg fault. even after successfully resolving hundreds of unique 253 character length domains at once with curl + parallel

rofl0r commented 2 weeks ago

thanks, fixed in master.

itsjfx commented 2 weeks ago

thank you !