[sanitizer] Share TSan accept & accept4 interceptors with other sanitizers.

llvm-svn: 182835
This commit is contained in:
Evgeniy Stepanov 2013-05-29 09:09:58 +00:00
parent 490bc1a27f
commit 08f662845d
6 changed files with 135 additions and 51 deletions

View File

@ -107,16 +107,22 @@ using namespace __asan; // NOLINT
#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
ASAN_WRITE_RANGE(ptr, size)
#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) ASAN_READ_RANGE(ptr, size)
#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
do { \
if (asan_init_is_running) \
return REAL(func)(__VA_ARGS__); \
ctx = 0; \
(void)ctx; \
ENSURE_ASAN_INITED(); \
#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
do { \
if (asan_init_is_running) return REAL(func)(__VA_ARGS__); \
ctx = 0; \
(void) ctx; \
ENSURE_ASAN_INITED(); \
} while (false)
#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
do { \
} while (false)
#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
do { \
} while (false)
#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
do { \
} while (false)
#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) do { } while (false)
#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) do { } while (false)
#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) SetThreadName(name)
#include "sanitizer_common/sanitizer_common_interceptors.inc"

View File

@ -985,18 +985,24 @@ struct MSanInterceptorContext {
__msan_unpoison(ptr, size)
#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
CHECK_UNPOISONED_CTX(ctx, ptr, size);
#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
if (msan_init_is_running) return REAL(func)(__VA_ARGS__); \
MSanInterceptorContext msan_ctx = { IsInInterceptorScope() }; \
ctx = (void *)&msan_ctx; \
InterceptorScope interceptor_scope; \
#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
if (msan_init_is_running) return REAL(func)(__VA_ARGS__); \
MSanInterceptorContext msan_ctx = {IsInInterceptorScope()}; \
ctx = (void *)&msan_ctx; \
InterceptorScope interceptor_scope; \
ENSURE_MSAN_INITED();
#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
do { \
} while (false)
#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) do { } while (false)
#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
do { \
} while (false)
#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
do { \
} while (false)
#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
do { } while (false) // FIXME
do { \
} while (false) // FIXME
#include "sanitizer_common/sanitizer_common_interceptors.inc"
#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) CHECK_UNPOISONED(p, s)

View File

@ -651,6 +651,44 @@ TEST(MemorySanitizer, bind_getsockname) {
close(sock);
}
TEST(MemorySanitizer, accept) {
int listen_socket = socket(AF_INET, SOCK_STREAM, 0);
ASSERT_LT(0, listen_socket);
struct sockaddr_in sai;
sai.sin_family = AF_INET;
sai.sin_port = 0;
sai.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
int res = bind(listen_socket, (struct sockaddr *)&sai, sizeof(sai));
ASSERT_EQ(0, res);
res = listen(listen_socket, 1);
ASSERT_EQ(0, res);
socklen_t sz = sizeof(sai);
res = getsockname(listen_socket, (struct sockaddr *)&sai, &sz);
ASSERT_EQ(0, res);
ASSERT_EQ(sizeof(sai), sz);
int connect_socket = socket(AF_INET, SOCK_STREAM, 0);
ASSERT_LT(0, connect_socket);
res = fcntl(connect_socket, F_SETFL, O_NONBLOCK);
ASSERT_EQ(0, res);
res = connect(connect_socket, (struct sockaddr *)&sai, sizeof(sai));
ASSERT_EQ(-1, res);
ASSERT_EQ(EINPROGRESS, errno);
__msan_poison(&sai, sizeof(sai));
int new_sock = accept(listen_socket,(struct sockaddr *)&sai, &sz);
ASSERT_LT(0, new_sock);
ASSERT_EQ(sizeof(sai), sz);
EXPECT_NOT_POISONED(sai);
close(new_sock);
close(connect_socket);
close(listen_socket);
}
#define EXPECT_HOSTENT_NOT_POISONED(he) \
do { \
EXPECT_NOT_POISONED(*(he)); \

View File

@ -962,6 +962,52 @@ INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
#define INIT_GETSOCKOPT
#endif
#if SANITIZER_INTERCEPT_ACCEPT
INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);
unsigned addrlen0;
if (addrlen) {
COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
addrlen0 = *addrlen;
}
int fd2 = REAL(accept)(fd, addr, addrlen);
if (fd2 >= 0) {
if (fd >= 0)
COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
if (addr && addrlen)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
}
return fd2;
}
#define INIT_ACCEPT INTERCEPT_FUNCTION(accept);
#else
#define INIT_ACCEPT
#endif
#if SANITIZER_INTERCEPT_ACCEPT4
INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);
unsigned addrlen0;
if (addrlen) {
COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
addrlen0 = *addrlen;
}
int fd2 = REAL(accept4)(fd, addr, addrlen, f);
if (fd2 >= 0) {
if (fd >= 0)
COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
if (addr && addrlen)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
}
return fd2;
}
#define INIT_ACCEPT4 INTERCEPT_FUNCTION(accept4);
#else
#define INIT_ACCEPT4
#endif
#define SANITIZER_COMMON_INTERCEPTORS_INIT \
INIT_STRCASECMP; \
INIT_STRNCASECMP; \
@ -989,4 +1035,6 @@ INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
INIT_GETSOCKNAME; \
INIT_GETHOSTBYNAME; \
INIT_GETHOSTBYNAME_R; \
INIT_GETSOCKOPT;
INIT_GETSOCKOPT; \
INIT_ACCEPT; \
INIT_ACCEPT4;

View File

@ -75,5 +75,7 @@
# define SANITIZER_INTERCEPT_GETHOSTBYNAME SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_GETHOSTBYNAME_R SI_LINUX
# define SANITIZER_INTERCEPT_GETSOCKOPT SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_ACCEPT SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_ACCEPT4 SI_LINUX
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H

View File

@ -1392,22 +1392,6 @@ TSAN_INTERCEPTOR(int, listen, int fd, int backlog) {
return res;
}
TSAN_INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
SCOPED_TSAN_INTERCEPTOR(accept, fd, addr, addrlen);
int fd2 = REAL(accept)(fd, addr, addrlen);
if (fd >= 0 && fd2 >= 0)
FdSocketAccept(thr, pc, fd, fd2);
return fd2;
}
TSAN_INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
SCOPED_TSAN_INTERCEPTOR(accept4, fd, addr, addrlen, f);
int fd2 = REAL(accept4)(fd, addr, addrlen, f);
if (fd >= 0 && fd2 >= 0)
FdSocketAccept(thr, pc, fd, fd2);
return fd2;
}
TSAN_INTERCEPTOR(int, epoll_create, int size) {
SCOPED_TSAN_INTERCEPTOR(epoll_create, size);
int fd = REAL(epoll_create)(size);
@ -1842,25 +1826,27 @@ struct TsanInterceptorContext {
// Causes interceptor recursion (glob64() calls lstat64())
#undef SANITIZER_INTERCEPT_GLOB
#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
MemoryAccessRange(((TsanInterceptorContext*)ctx)->thr, \
((TsanInterceptorContext*)ctx)->pc, \
(uptr)ptr, size, true)
#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
MemoryAccessRange(((TsanInterceptorContext*)ctx)->thr, \
((TsanInterceptorContext*)ctx)->pc, \
(uptr)ptr, size, false)
#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
SCOPED_TSAN_INTERCEPTOR(func, __VA_ARGS__) \
TsanInterceptorContext _ctx = {thr, caller_pc, pc}; \
ctx = (void*)&_ctx; \
(void)ctx;
#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
MemoryAccessRange(((TsanInterceptorContext *) ctx)->thr, \
((TsanInterceptorContext *) ctx)->pc, (uptr) ptr, size, \
true)
#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
MemoryAccessRange(((TsanInterceptorContext *) ctx)->thr, \
((TsanInterceptorContext *) ctx)->pc, (uptr) ptr, size, \
false)
#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
SCOPED_TSAN_INTERCEPTOR(func, __VA_ARGS__); \
TsanInterceptorContext _ctx = {thr, caller_pc, pc}; \
ctx = (void *)&_ctx; \
(void) ctx;
#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
FdAcquire(((TsanInterceptorContext*)ctx)->thr, pc, fd)
FdAcquire(((TsanInterceptorContext *) ctx)->thr, pc, fd)
#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
FdRelease(((TsanInterceptorContext*)ctx)->thr, pc, fd)
FdRelease(((TsanInterceptorContext *) ctx)->thr, pc, fd)
#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
FdSocketAccept(((TsanInterceptorContext *) ctx)->thr, pc, fd, newfd)
#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
ThreadSetName(((TsanInterceptorContext*)ctx)->thr, name)
ThreadSetName(((TsanInterceptorContext *) ctx)->thr, name)
#include "sanitizer_common/sanitizer_common_interceptors.inc"
// FIXME: Implement these with MemoryAccessRange().
@ -2062,8 +2048,6 @@ void InitializeInterceptors() {
TSAN_INTERCEPT(connect);
TSAN_INTERCEPT(bind);
TSAN_INTERCEPT(listen);
TSAN_INTERCEPT(accept);
TSAN_INTERCEPT(accept4);
TSAN_INTERCEPT(epoll_create);
TSAN_INTERCEPT(epoll_create1);
TSAN_INTERCEPT(close);