[tor-commits] [torsocks/master] Fix: overload _exit and _Exit to cleanup library

dgoulet at torproject.org dgoulet at torproject.org
Fri Apr 4 22:40:27 UTC 2014


commit ebd68449a67a514819daa1e263f936806c1fd60b
Author: David Goulet <dgoulet at ev0ke.net>
Date:   Sun Nov 10 20:48:37 2013 -0500

    Fix: overload _exit and _Exit to cleanup library
    
    Some application directly calls _exit (or exit_group on Linux) like SSH
    does when a DNS name resolution fails. Those two functions don't call
    the library destructor thus not cleaning the library cleanly.
    
    Signed-off-by: David Goulet <dgoulet at ev0ke.net>
---
 src/lib/Makefile.am |    3 +-
 src/lib/exit.c      |   77 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/lib/torsocks.c  |   20 +++++++++----
 src/lib/torsocks.h  |    1 +
 4 files changed, 94 insertions(+), 7 deletions(-)

diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index f7320e3..dbf8c77 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -8,7 +8,8 @@ lib_LTLIBRARIES = libtorsocks.la
 
 libtorsocks_la_SOURCES = torsocks.c torsocks.h \
                          connect.c gethostbyname.c getaddrinfo.c close.c \
-                         getpeername.c socket.c syscall.c socketpair.c recv.c
+                         getpeername.c socket.c syscall.c socketpair.c recv.c \
+                         exit.c
 
 libtorsocks_la_LIBADD = $(top_builddir)/src/common/libcommon.la
 if ! HAVE_BUILTIN_DL
diff --git a/src/lib/exit.c b/src/lib/exit.c
new file mode 100644
index 0000000..ce4655f
--- /dev/null
+++ b/src/lib/exit.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) - 2013 - David Goulet <dgoulet at ev0ke.net>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License, version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 51
+ * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "torsocks.h"
+
+/*
+ * _exit() and _Exit are hijacked here so we can cleanup torsocks library
+ * safely since the constructor is *not* called for these functions.
+ */
+
+void _exit(int status)
+{
+	static void (*plibc_func)(int) = NULL;
+
+	if (plibc_func == NULL) {
+		plibc_func = dlsym(RTLD_NEXT, "_exit");
+		if (plibc_func == NULL) {
+			ERR("unable to find \"_exit\" symbol");
+			errno = ENOSYS;
+		}
+	}
+
+	tsocks_cleanup();
+
+	if (plibc_func) {
+		plibc_func(status);
+	}
+
+	/*
+	 * This should never be reached but for the sake of the compiler
+	 * not complaining, this function MUST never return.
+	 */
+	abort();
+}
+
+void _Exit(int status)
+{
+	static void (*plibc_func)(int) = NULL;
+
+	if (plibc_func == NULL) {
+		plibc_func = dlsym(RTLD_NEXT, "_Exit");
+		if (plibc_func == NULL) {
+			ERR("unable to find \"_Exit\" symbol");
+			errno = ENOSYS;
+		}
+	}
+
+	tsocks_cleanup();
+
+	if (plibc_func) {
+		plibc_func(status);
+	}
+
+	/*
+	 * This should never be reached but for the sake of the compiler
+	 * not complaining, this function MUST never return.
+	 */
+	abort();
+}
diff --git a/src/lib/torsocks.c b/src/lib/torsocks.c
index 332c561..f1de9c5 100644
--- a/src/lib/torsocks.c
+++ b/src/lib/torsocks.c
@@ -242,12 +242,7 @@ static void __attribute__((constructor)) tsocks_init(void)
  */
 static void __attribute__((destructor)) tsocks_exit(void)
 {
-	/* Cleanup every entries in the onion pool. */
-	onion_pool_destroy(&tsocks_onion_pool);
-	/* Cleanup allocated memory in the config file. */
-	config_file_destroy(&tsocks_config.conf_file);
-	/* Clean up logging. */
-	log_destroy();
+	tsocks_cleanup();
 }
 
 /*
@@ -529,3 +524,16 @@ void *tsocks_find_libc_symbol(const char *symbol,
 
 	return fct_ptr;
 }
+
+/*
+ * Cleanup torsocks library memory and open fd.
+ */
+void tsocks_cleanup(void)
+{
+	/* Cleanup every entries in the onion pool. */
+	onion_pool_destroy(&tsocks_onion_pool);
+	/* Cleanup allocated memory in the config file. */
+	config_file_destroy(&tsocks_config.conf_file);
+	/* Clean up logging. */
+	log_destroy();
+}
diff --git a/src/lib/torsocks.h b/src/lib/torsocks.h
index d724a77..c5466a1 100644
--- a/src/lib/torsocks.h
+++ b/src/lib/torsocks.h
@@ -342,5 +342,6 @@ void *tsocks_find_libc_symbol(const char *symbol,
 		enum tsocks_sym_action action);
 int tsocks_tor_resolve(const char *hostname, uint32_t *ip_addr);
 int tsocks_tor_resolve_ptr(const char *addr, char **ip, int af);
+void tsocks_cleanup(void);
 
 #endif /* TORSOCKS_H */





More information about the tor-commits mailing list