commit f97b07ef921dbcaef8cb6718179bce21b4714e77
Author: David Goulet <dgoulet(a)ev0ke.net>
Date: Fri Oct 24 13:12:14 2014 -0400
Stop denying syscall() and add dangerous ones
This patch should support all dangerous syscall() that can leak to the
network without going through the Tor network. With this, we can stop
denying arbitrary syscalls through the syscall() function.
Signed-off-by: David Goulet <dgoulet(a)ev0ke.net>
---
src/common/compat.h | 15 ++++++++++++
src/lib/syscall.c | 68 +++++++++++++++++++++++++++++++++++++++++++++------
src/lib/torsocks.h | 3 +++
3 files changed, 78 insertions(+), 8 deletions(-)
diff --git a/src/common/compat.h b/src/common/compat.h
index f572563..766b1fd 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -75,6 +75,15 @@ void tsocks_mutex_unlock(tsocks_mutex_t *m);
#ifndef __NR_accept
#define __NR_accept -6
#endif
+#ifndef __NR_getpeername
+#define __NR_getpeername -7
+#endif
+#ifndef __NR_listen
+#define __NR_listen -8
+#endif
+#ifndef __NR_recvmsg
+#define __NR_recvmsg -9
+#endif
#define TSOCKS_NR_SOCKET __NR_socket
#define TSOCKS_NR_CONNECT __NR_connect
@@ -82,6 +91,9 @@ void tsocks_mutex_unlock(tsocks_mutex_t *m);
#define TSOCKS_NR_MMAP __NR_mmap
#define TSOCKS_NR_MUNMAP __NR_munmap
#define TSOCKS_NR_ACCEPT __NR_accept
+#define TSOCKS_NR_GETPEERNAME __NR_getpeername
+#define TSOCKS_NR_LISTEN __NR_listen
+#define TSOCKS_NR_RECVMSG __NR_recvmsg
#endif /* __linux__ */
@@ -100,6 +112,9 @@ void tsocks_mutex_unlock(tsocks_mutex_t *m);
#define TSOCKS_NR_MMAP SYS_mmap
#define TSOCKS_NR_MUNMAP SYS_munmap
#define TSOCKS_NR_ACCEPT SYS_accept
+#define TSOCKS_NR_GETPEERNAME SYS_getpeername
+#define TSOCKS_NR_LISTEN SYS_listen
+#define TSOCKS_NR_RECVMSG SYS_recvmsg
#endif /* __FreeBSD__, __FreeBSD_kernel__, __darwin__, __NetBSD__ */
diff --git a/src/lib/syscall.c b/src/lib/syscall.c
index 9de6744..7b8d45a 100644
--- a/src/lib/syscall.c
+++ b/src/lib/syscall.c
@@ -121,6 +121,50 @@ static LIBC_SYSCALL_RET_TYPE handle_munmap(va_list args)
}
/*
+ * Handle getpeername(2) syscall.
+ */
+static LIBC_GETPEERNAME_RET_TYPE handle_getpeername(va_list args)
+{
+ int sockfd;
+ struct sockaddr *addr;
+ socklen_t *addrlen;
+
+ sockfd = va_arg(args, __typeof__(sockfd));
+ addr = va_arg(args, __typeof__(addr));
+ addrlen = va_arg(args, __typeof__(addrlen));
+
+ return tsocks_getpeername(sockfd, addr, addrlen);
+}
+
+/*
+ * Handle listen(2) syscall.
+ */
+static LIBC_LISTEN_RET_TYPE handle_listen(va_list args)
+{
+ int sockfd, backlog;
+
+ sockfd = va_arg(args, __typeof__(sockfd));
+ backlog = va_arg(args, __typeof__(backlog));
+
+ return tsocks_listen(sockfd, backlog);
+}
+
+/*
+ * Handle recvmsg(2) syscall.
+ */
+static LIBC_RECVMSG_RET_TYPE handle_recvmsg(va_list args)
+{
+ int sockfd, flags;
+ struct msghdr *msg;
+
+ sockfd = va_arg(args, __typeof__(sockfd));
+ msg = va_arg(args, __typeof__(msg));
+ flags = va_arg(args, __typeof__(flags));
+
+ return tsocks_recvmsg(sockfd, msg, flags);
+}
+
+/*
* Torsocks call for syscall(2)
*/
LIBC_SYSCALL_RET_TYPE tsocks_syscall(long int number, va_list args)
@@ -175,15 +219,18 @@ LIBC_SYSCALL_RET_TYPE tsocks_syscall(long int number, va_list args)
case TSOCKS_NR_ACCEPT:
ret = handle_accept(args);
break;
+ case TSOCKS_NR_GETPEERNAME:
+ ret = handle_getpeername(args);
+ break;
+ case TSOCKS_NR_LISTEN:
+ ret = handle_listen(args);
+ break;
+ case TSOCKS_NR_RECVMSG:
+ ret = handle_recvmsg(args);
+ break;
default:
- /*
- * Deny call since we have no idea if this call can leak or not data
- * off the Tor network.
- */
- WARN("[syscall] Unsupported syscall number %ld. Denying the call",
- number);
- ret = -1;
- errno = ENOSYS;
+ /* Safe to call the libc syscall function. */
+ ret = tsocks_libc_syscall(number, args);
break;
}
@@ -198,6 +245,11 @@ LIBC_SYSCALL_DECL
LIBC_SYSCALL_RET_TYPE ret;
va_list args;
+ if (!tsocks_libc_syscall) {
+ 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);
diff --git a/src/lib/torsocks.h b/src/lib/torsocks.h
index 1a4219c..6ded557 100644
--- a/src/lib/torsocks.h
+++ b/src/lib/torsocks.h
@@ -273,6 +273,7 @@ TSOCKS_DECL(connect, LIBC_CONNECT_RET_TYPE, LIBC_CONNECT_SIG)
/* recvmsg(2) */
extern TSOCKS_LIBC_DECL(recvmsg, LIBC_RECVMSG_RET_TYPE, LIBC_RECVMSG_SIG)
+TSOCKS_DECL(recvmsg, LIBC_RECVMSG_RET_TYPE, LIBC_RECVMSG_SIG)
#define LIBC_RECVMSG_DECL \
LIBC_RECVMSG_RET_TYPE LIBC_RECVMSG_NAME(LIBC_RECVMSG_SIG)
@@ -357,6 +358,7 @@ extern TSOCKS_LIBC_DECL(getaddrinfo, LIBC_GETADDRINFO_RET_TYPE,
/* getpeername(2) */
extern TSOCKS_LIBC_DECL(getpeername, LIBC_GETPEERNAME_RET_TYPE,
LIBC_GETPEERNAME_SIG)
+TSOCKS_DECL(getpeername, LIBC_GETPEERNAME_RET_TYPE, LIBC_GETPEERNAME_SIG)
#define LIBC_GETPEERNAME_DECL LIBC_GETPEERNAME_RET_TYPE \
LIBC_GETPEERNAME_NAME(LIBC_GETPEERNAME_SIG)
@@ -375,6 +377,7 @@ extern TSOCKS_LIBC_DECL(accept4, LIBC_ACCEPT4_RET_TYPE, LIBC_ACCEPT4_SIG)
/* listen(2) */
extern TSOCKS_LIBC_DECL(listen, LIBC_LISTEN_RET_TYPE, LIBC_LISTEN_SIG)
+TSOCKS_DECL(listen, LIBC_LISTEN_RET_TYPE, LIBC_LISTEN_SIG)
#define LIBC_LISTEN_DECL LIBC_LISTEN_RET_TYPE \
LIBC_LISTEN_NAME(LIBC_LISTEN_SIG)