On Tuesday 24 April 2018 12:07:10 Philip Guenther wrote:
> On Tue, 24 Apr 2018, Jeremie Courreges-Anglas wrote:
> ...
> 
> > We took a quick look yesterday, the crash happens in dtors, the cause of
> > the crash looks like a use after free.  I'm not a BIO_* hacker, here's
> > a stack trace on amd64, curl rebuilt with DEBUG=-g:
> > 
> > Program received signal SIGBUS, Bus error.
> > p 0x000005738701c2d7 in BIO_write (b=0x5735f58b080, in=0x573e9a05400,
> > inl=24) at /usr/src/lib/libcrypto/bio/bio_lib.c:289 289             if
> > ((b->method == NULL) || (b->method->bwrite == NULL)) { (gdb) p *b
> > $1 = {method = 0xdfdfdfdfdfdfdfdf, callback = 0xdfdfdfdfdfdfdfdf, cb_arg =
> > 0xdfdfdfdfdfdfdfdf <error: Cannot access memory at address
> > 0xdfdfdfdfdfdfdfdf>, init = -538976289, shutdown = -538976289, flags =
> > -538976289,> 
> >   retry_reason = -538976289, num = -538976289, ptr = 0xdfdfdfdfdfdfdfdf,
> >   next_bio = 0xdfdfdfdfdfdfdfdf, prev_bio = 0xdfdfdfdfdfdfdfdf,
> >   references = -538976289, num_read = 16131858542891098079, num_write =
> >   16131858542891098079, ex_data = {sk = 0xdfdfdfdfdfdfdfdf}}> 
> > (gdb) bt
> > #0  0x000005738701c2d7 in BIO_write (b=0x5735f58b080, in=0x573e9a05400,
> > inl=24) at /usr/src/lib/libcrypto/bio/bio_lib.c:289 #1 
> > 0x00000573bd3467ab in __sflush (fp=0x573bd5b9410 <usual>) at
> > /usr/src/lib/libc/stdio/fflush.c:80 #2  0x00000573bd34aa5f in _fwalk
> > (function=0x573bd346740 <__sflush>) at /usr/src/lib/libc/stdio/fwalk.c:50
> > #3  0x00000573bd2ffd8c in _libc___cxa_finalize (dso=0x0) at
> > /usr/src/lib/libc/stdlib/atexit.c:177 #4  0x00000573bd2ea9f1 in
> > _libc_exit (status=0) at /usr/src/lib/libc/stdlib/exit.c:54 #5 
> > 0x00000570ee100b0d in _start ()
> > (gdb)
> 
> So these BIOs are used with funopen()?  I smells like the BIO is being
> closed directly instead of being closed with fclose(), with the result
> that stdio still has a reference to it and you get the flush later trying
> to access the freed BIO.

This is a bug in torsocks - torsocks is just a shell script that preloads 
libtorsocks.so, which hijacks a bunch of libc symbols. Their implementation 
for fclose() is broken and does not work properly with things that have been 
funopen()'d - in short, they call fileno() and check that the resulting fd > 0 
and if it is not they return without calling the libc fclose(). This leaves a 
dangling fp, which the dtors later try to flush. The fix is probably to 
unconditionally call the libc fclose() regardless of what the fd is. FWIW in 
this case the corresponding funopen is from libcrypto's BIO_vprintf().

Reply via email to