commit ce460ba3e9931a5ab8d7f27c9dc46eb325bcbf07 Author: David Goulet dgoulet@ev0ke.net Date: Wed Aug 7 08:01:28 2013 -0400
Add syscall(2) support
At this commit, only close, connect and socket are handled through syscall(2).
Signed-off-by: David Goulet dgoulet@ev0ke.net --- src/lib/Makefile.am | 2 +- src/lib/socket.c | 3 ++ src/lib/syscall.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/torsocks.h | 25 ++++++++++++ 4 files changed, 140 insertions(+), 1 deletion(-)
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index d107fc8..0f764f1 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -12,7 +12,7 @@ lib_LTLIBRARIES = libtorsocks.la
libtorsocks_la_SOURCES = torsocks.c torsocks.h \ connect.c gethostbyname.c getaddrinfo.c close.c \ - getpeername.c socket.c + getpeername.c socket.c syscall.c
libtorsocks_la_LIBADD = \ $(top_builddir)/src/common/libcommon.la \ diff --git a/src/lib/socket.c b/src/lib/socket.c index 69d28e6..1f543e5 100644 --- a/src/lib/socket.c +++ b/src/lib/socket.c @@ -26,6 +26,9 @@ */ LIBC_SOCKET_RET_TYPE tsocks_socket(LIBC_SOCKET_SIG) { + DBG("[socket] Creating socket with domain %d, type %d and protocol %d", + __domain, __type, __protocol); + switch (__type) { case SOCK_STREAM: break; diff --git a/src/lib/syscall.c b/src/lib/syscall.c new file mode 100644 index 0000000..5cb9e8f --- /dev/null +++ b/src/lib/syscall.c @@ -0,0 +1,111 @@ +/* + * 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 <assert.h> +#include <stdarg.h> + +#include <common/log.h> + +#include "torsocks.h" + +/* + * Handle close syscall to be called with tsocks call. + */ +static LIBC_CLOSE_RET_TYPE handle_close(va_list args) +{ + int fd; + + fd = va_arg(args, int); + + return tsocks_close(fd); +} + +/* + * Handle socket syscall to go through Tor. + */ +static LIBC_SOCKET_RET_TYPE handle_socket(va_list args) +{ + int domain, type, protocol; + + domain = va_arg(args, int); + type = va_arg(args, int); + protocol = va_arg(args, int); + + return tsocks_socket(domain, type, protocol); +} + +/* + * Handle connect syscall to go through Tor. + */ +static LIBC_CONNECT_RET_TYPE handle_connect(va_list args) +{ + int sockfd; + const struct sockaddr *addr; + socklen_t addrlen; + + sockfd = va_arg(args, int); + addr = va_arg(args, const struct sockaddr *); + addrlen = va_arg(args, socklen_t); + + return tsocks_connect(sockfd, addr, addrlen); +} + +/* + * Torsocks call for syscall(2) + */ +LIBC_SYSCALL_RET_TYPE tsocks_syscall(long int __number, va_list args) +{ + long int ret; + + DBG("[syscall] Syscall libc wrapper number %ld called", __number); + + switch (__number) { + case __NR_socket: + ret = handle_socket(args); + break; + case __NR_connect: + ret = handle_connect(args); + break; + case __NR_close: + ret = handle_close(args); + break; + default: + ret = tsocks_libc_syscall(__number, args); + break; + } + + return ret; +} + +/* + * Libc hijacked symbol syscall(2). + */ +LIBC_SYSCALL_DECL +{ + LIBC_SYSCALL_RET_TYPE ret; + va_list args; + + /* Find symbol if not already set. Exit if not found. */ + tsocks_libc_syscall = tsocks_find_libc_symbol(LIBC_SYSCALL_NAME_STR, + TSOCKS_SYM_EXIT_NOT_FOUND); + + va_start(args, __number); + ret = tsocks_syscall(__number, args); + va_end(args); + + return ret; +} diff --git a/src/lib/torsocks.h b/src/lib/torsocks.h index b8da8ca..c6191e2 100644 --- a/src/lib/torsocks.h +++ b/src/lib/torsocks.h @@ -30,6 +30,8 @@ */ #define TSOCKS_LIBC_DECL(name, type, sig) \ type (*tsocks_libc_##name)(sig); +#define TSOCKS_DECL(name, type, sig) \ + extern type tsocks_##name(sig);
#if (defined(__linux__) || defined(__FreeBSD__) || defined(__darwin__))
@@ -154,6 +156,21 @@ struct hostent **__result, int *__h_errnop #error "OS not supported." #endif /* __linux__ , __FreeBSD__, __darwin__ */
+#if (defined(__linux__)) + +#define _GNU_SOURCE +#include <unistd.h> +#include <sys/syscall.h> + +/* syscall(2) */ +#define LIBC_SYSCALL_NAME syscall +#define LIBC_SYSCALL_NAME_STR XSTR(LIBC_SYSCALL_NAME) +#define LIBC_SYSCALL_RET_TYPE long int +#define LIBC_SYSCALL_SIG long int __number, ... +#define LIBC_SYSCALL_ARGS __number + +#endif /* __linux__ */ + /* * The following defines are libc function declarations using the macros * defined above on a per OS basis. @@ -161,16 +178,24 @@ struct hostent **__result, int *__h_errnop
/* connect(2) */ TSOCKS_LIBC_DECL(connect, LIBC_CONNECT_RET_TYPE, LIBC_CONNECT_SIG) +TSOCKS_DECL(connect, LIBC_CONNECT_RET_TYPE, LIBC_CONNECT_SIG) #define LIBC_CONNECT_DECL \ LIBC_CONNECT_RET_TYPE LIBC_CONNECT_NAME(LIBC_CONNECT_SIG)
/* socket(2) */ TSOCKS_LIBC_DECL(socket, LIBC_SOCKET_RET_TYPE, LIBC_SOCKET_SIG) +TSOCKS_DECL(socket, LIBC_SOCKET_RET_TYPE, LIBC_SOCKET_SIG) #define LIBC_SOCKET_DECL \ LIBC_SOCKET_RET_TYPE LIBC_SOCKET_NAME(LIBC_SOCKET_SIG)
+/* syscall(2) */ +TSOCKS_LIBC_DECL(syscall, LIBC_SYSCALL_RET_TYPE, LIBC_SYSCALL_SIG) +#define LIBC_SYSCALL_DECL \ + LIBC_SYSCALL_RET_TYPE LIBC_SYSCALL_NAME(LIBC_SYSCALL_SIG) + /* close(2) */ TSOCKS_LIBC_DECL(close, LIBC_CLOSE_RET_TYPE, LIBC_CLOSE_SIG) +TSOCKS_DECL(close, LIBC_CLOSE_RET_TYPE, LIBC_CLOSE_SIG) #define LIBC_CLOSE_DECL \ LIBC_CLOSE_RET_TYPE LIBC_CLOSE_NAME(LIBC_CLOSE_SIG)
tor-commits@lists.torproject.org