commit 1065e551161dfaa8f28da89b64bb57a3ea22d5df Author: David Goulet dgoulet@ev0ke.net Date: Wed Nov 6 18:49:42 2013 -0500
Add __syscall support for *BSD systems
Fixes #17
Signed-off-by: David Goulet dgoulet@ev0ke.net --- src/lib/syscall.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/torsocks.h | 26 ++++++++++++++++++ 2 files changed, 104 insertions(+)
diff --git a/src/lib/syscall.c b/src/lib/syscall.c index 67d3de2..adc433b 100644 --- a/src/lib/syscall.c +++ b/src/lib/syscall.c @@ -68,6 +68,7 @@ static LIBC_CONNECT_RET_TYPE handle_connect(va_list args) return tsocks_connect(sockfd, addr, addrlen); }
+#if (defined(__linux__) || defined(__darwin__)) /* * Handle mmap(2) syscall. */ @@ -87,6 +88,7 @@ static LIBC_SYSCALL_RET_TYPE handle_mmap(va_list args)
return (LIBC_SYSCALL_RET_TYPE) mmap(addr, len, prot, flags, fd, offset); } +#endif /* __linux__, __darwin__ */
/* * Handle munmap(2) syscall. @@ -120,6 +122,14 @@ LIBC_SYSCALL_RET_TYPE tsocks_syscall(long int __number, va_list args) ret = handle_close(args); break; case TSOCKS_NR_MMAP: +#if (defined(__NetBSD__) || defined(__FreeBSD__)) && defined(__x86_64) + /* + * On an 64 bit *BSD system, __syscall(2) should be used for mmap(). + * This is NOT suppose to happen but for protection we deny that call. + */ + ret = -1; + errno = ENOSYS; +#else /* * The mmap/munmap syscall are handled here for a very specific case so * buckle up here for the explanation :). @@ -141,6 +151,7 @@ LIBC_SYSCALL_RET_TYPE tsocks_syscall(long int __number, va_list args) * own memory using mmap() called by syscall(). Same for munmap(). */ ret = handle_mmap(args); +#endif /* __NetBSD__, __FreeBSD__, __x86_64 */ break; case TSOCKS_NR_MUNMAP: ret = handle_munmap(args); @@ -174,3 +185,70 @@ LIBC_SYSCALL_DECL
return ret; } + +/* Only used for *BSD systems. */ +#if (defined(__NetBSD__) || defined(__FreeBSD__)) + +/* __syscall(2) */ +TSOCKS_LIBC_DECL(__syscall, LIBC___SYSCALL_RET_TYPE, LIBC___SYSCALL_SIG) + +/* + * Handle *BSD mmap(2) syscall. + */ +static LIBC___SYSCALL_RET_TYPE handle_bsd_mmap(va_list args) +{ + void *addr; + size_t len; + int prot, flags, fd; + off_t offset; + + addr = va_arg(args, __typeof__(addr)); + len = va_arg(args, __typeof__(len)); + prot = va_arg(args, __typeof__(prot)); + flags = va_arg(args, __typeof__(flags)); + fd = va_arg(args, __typeof__(fd)); + offset = va_arg(args, __typeof__(offset)); + + return (LIBC___SYSCALL_RET_TYPE) mmap(addr, len, prot, flags, fd, offset); +} + +LIBC___SYSCALL_RET_TYPE tsocks___syscall(quad_t __number, va_list args) +{ + LIBC_SYSCALL_RET_TYPE ret; + + switch (__number) { + case TSOCKS_NR_MMAP: + /* + * Please see the mmap comment in the syscall() function to understand + * why mmap is being hijacked. + */ + ret = handle_bsd_mmap(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; + break; + } + + return ret; +} + +LIBC___SYSCALL_DECL +{ + LIBC___SYSCALL_RET_TYPE ret; + va_list args; + + va_start(args, __number); + ret = tsocks___syscall(__number, args); + va_end(args); + + return ret; +} + +#endif /* __NetBSD__, __FreeBSD__ */ diff --git a/src/lib/torsocks.h b/src/lib/torsocks.h index 78dc3ec..d724a77 100644 --- a/src/lib/torsocks.h +++ b/src/lib/torsocks.h @@ -208,6 +208,25 @@ struct hostent **__result, int *__h_errnop
#endif /* __GLIBC__ && __FreeBSD_kernel__ */
+/* __syscall(2) */ +#if defined(__FreeBSD__) + +#define LIBC___SYSCALL_NAME __syscall +#define LIBC___SYSCALL_NAME_STR XSTR(LIBC___SYSCALL_NAME) +#define LIBC___SYSCALL_RET_TYPE off_t +#define LIBC___SYSCALL_SIG quad_t __number, ... +#define LIBC___SYSCALL_ARGS __number + +#elif defined(__NetBSD__) + +#define LIBC___SYSCALL_NAME __syscall +#define LIBC___SYSCALL_NAME_STR XSTR(LIBC___SYSCALL_NAME) +#define LIBC___SYSCALL_RET_TYPE quad_t +#define LIBC___SYSCALL_SIG quad_t __number, ... +#define LIBC___SYSCALL_ARGS __number + +#endif /* __FreeBSD__, __NetBSD__ */ + /* * The following defines are libc function declarations using the macros * defined above on a per OS basis. @@ -241,6 +260,13 @@ extern 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)
+/* __syscall(2) */ +#if (defined(__FreeBSD__) || defined(__NetBSD__)) +extern 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) +#endif /* __FreeBSD__, __NetBSD__ */ + /* close(2) */ extern TSOCKS_LIBC_DECL(close, LIBC_CLOSE_RET_TYPE, LIBC_CLOSE_SIG) TSOCKS_DECL(close, LIBC_CLOSE_RET_TYPE, LIBC_CLOSE_SIG)