forked from OSchip/llvm-project
[sanitizer] Share TSan accept & accept4 interceptors with other sanitizers.
llvm-svn: 182835
This commit is contained in:
parent
490bc1a27f
commit
08f662845d
|
@ -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"
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)); \
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue