On Wednesday 25 April 2018 15:29:32 Joel Sing wrote:
> 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().
This appears to resolve the issue:
Index: Makefile
===================================================================
RCS file: /cvs/ports/net/torsocks/Makefile,v
retrieving revision 1.11
diff -u -p -u -p -r1.11 Makefile
--- Makefile 29 Jan 2018 21:44:30 -0000 1.11
+++ Makefile 25 Apr 2018 09:03:23 -0000
@@ -3,6 +3,7 @@
COMMENT = socks proxy for use with tor
DISTNAME = torsocks-2.2.0
+REVSION = 0
GH_PROJECT = torsocks
GH_ACCOUNT = dgoulet
Index: patches/patch-src_lib_fclose_c
===================================================================
RCS file: patches/patch-src_lib_fclose_c
diff -N patches/patch-src_lib_fclose_c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_lib_fclose_c 25 Apr 2018 09:03:23 -0000
@@ -0,0 +1,21 @@
+$OpenBSD$
+
+Unbreak funopen usage with libtorsocks - always call the libc fclose
+function, even when fd < 0.
+
+Index: src/lib/fclose.c
+--- src/lib/fclose.c.orig
++++ src/lib/fclose.c
+@@ -64,11 +64,9 @@ LIBC_FCLOSE_RET_TYPE tsocks_fclose(LIBC_FCLOSE_SIG)
+ connection_put_ref(conn);
+ }
+
++error:
+ /* Return the original libc fclose. */
+ return tsocks_libc_fclose(fp);
+-
+-error:
+- return -1;
+ }
+
+ /*