commit ebd68449a67a514819daa1e263f936806c1fd60b Author: David Goulet dgoulet@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@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@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 */
tor-commits@lists.torproject.org