[sanitizer] Move TSan and MSan recvmsg interceptors to common.

llvm-svn: 182843
This commit is contained in:
Evgeniy Stepanov 2013-05-29 11:30:00 +00:00
parent 2b997d2914
commit a4d08c4e87
6 changed files with 89 additions and 47 deletions

View File

@ -710,33 +710,21 @@ INTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) {
}
INTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags,
void *srcaddr, void *addrlen) {
void *srcaddr, int *addrlen) {
ENSURE_MSAN_INITED();
SIZE_T srcaddr_sz;
if (srcaddr)
srcaddr_sz = __sanitizer_get_socklen_t(addrlen);
if (srcaddr) srcaddr_sz = *addrlen;
SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen);
if (res > 0) {
__msan_unpoison(buf, res);
if (srcaddr) {
SIZE_T sz = __sanitizer_get_socklen_t(addrlen);
SIZE_T sz = *addrlen;
__msan_unpoison(srcaddr, (sz < srcaddr_sz) ? sz : srcaddr_sz);
}
}
return res;
}
INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct msghdr *msg, int flags) {
ENSURE_MSAN_INITED();
SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
if (res > 0) {
for (SIZE_T i = 0; i < __sanitizer_get_msghdr_iovlen(msg); ++i)
__msan_unpoison(__sanitizer_get_msghdr_iov_iov_base(msg, i),
__sanitizer_get_msghdr_iov_iov_len(msg, i));
}
return res;
}
INTERCEPTOR(void *, calloc, SIZE_T nmemb, SIZE_T size) {
if (CallocShouldReturnNullDueToOverflow(size, nmemb)) return 0;
GET_MALLOC_STACK_TRACE;
@ -1200,7 +1188,6 @@ void InitializeInterceptors() {
INTERCEPT_FUNCTION(epoll_pwait);
INTERCEPT_FUNCTION(recv);
INTERCEPT_FUNCTION(recvfrom);
INTERCEPT_FUNCTION(recvmsg);
INTERCEPT_FUNCTION(dladdr);
INTERCEPT_FUNCTION(dlopen);
INTERCEPT_FUNCTION(dl_iterate_phdr);

View File

@ -1044,6 +1044,37 @@ INTERCEPTOR(long double, modfl, long double x, long double *iptr) {
#define INIT_MODF
#endif
#if SANITIZER_INTERCEPT_RECVMSG
static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg) {
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
if (msg->msg_name)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name,
REAL(strlen)((char *)msg->msg_name) + 1);
if (msg->msg_iov)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov, msg->msg_iovlen);
for (SIZE_T i = 0; i < msg->msg_iovlen; ++i)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov[i].iov_base,
msg->msg_iov[i].iov_len);
if (msg->msg_control)
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
}
INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,
int flags) {
void *ctx;
COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);
SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
if (res >= 0) {
if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
if (msg) write_msghdr(ctx, msg);
}
return res;
}
#define INIT_RECVMSG INTERCEPT_FUNCTION(recvmsg);
#else
#define INIT_RECVMSG
#endif
#define SANITIZER_COMMON_INTERCEPTORS_INIT \
INIT_STRCASECMP; \
INIT_STRNCASECMP; \
@ -1074,4 +1105,5 @@ INTERCEPTOR(long double, modfl, long double x, long double *iptr) {
INIT_GETSOCKOPT; \
INIT_ACCEPT; \
INIT_ACCEPT4; \
INIT_MODF;
INIT_MODF; \
INIT_RECVMSG;

View File

@ -78,5 +78,6 @@
# define SANITIZER_INTERCEPT_ACCEPT SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_ACCEPT4 SI_LINUX
# define SANITIZER_INTERCEPT_MODF SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_RECVMSG SI_NOT_WINDOWS
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H

View File

@ -81,22 +81,6 @@ namespace __sanitizer {
uptr sig_ign = (uptr)SIG_IGN;
uptr sig_dfl = (uptr)SIG_DFL;
void* __sanitizer_get_msghdr_iov_iov_base(void* msg, int idx) {
return ((struct msghdr *)msg)->msg_iov[idx].iov_base;
}
uptr __sanitizer_get_msghdr_iov_iov_len(void* msg, int idx) {
return ((struct msghdr *)msg)->msg_iov[idx].iov_len;
}
uptr __sanitizer_get_msghdr_iovlen(void* msg) {
return ((struct msghdr *)msg)->msg_iovlen;
}
uptr __sanitizer_get_socklen_t(void* socklen_ptr) {
return *(socklen_t*)socklen_ptr;
}
uptr __sanitizer_get_sigaction_sa_sigaction(void *act) {
struct sigaction *a = (struct sigaction *)act;
// Check that sa_sigaction and sa_handler are the same.
@ -136,6 +120,8 @@ COMPILER_CHECK(offsetof(struct __sanitizer_dl_phdr_info, dlpi_phnum) ==
offsetof(struct dl_phdr_info, dlpi_phnum));
#endif
COMPILER_CHECK(sizeof(socklen_t) == sizeof(unsigned));
COMPILER_CHECK(sizeof(struct __sanitizer_addrinfo) == sizeof(struct addrinfo));
COMPILER_CHECK(offsetof(struct __sanitizer_addrinfo, ai_addr) ==
offsetof(struct addrinfo, ai_addr));
@ -152,4 +138,34 @@ COMPILER_CHECK(offsetof(struct __sanitizer_hostent, h_aliases) ==
COMPILER_CHECK(offsetof(struct __sanitizer_hostent, h_addr_list) ==
offsetof(struct hostent, h_addr_list));
COMPILER_CHECK(sizeof(struct __sanitizer_iovec) == sizeof(struct iovec));
COMPILER_CHECK(offsetof(struct __sanitizer_iovec, iov_base) ==
offsetof(struct iovec, iov_base));
COMPILER_CHECK(offsetof(struct __sanitizer_iovec, iov_len) ==
offsetof(struct iovec, iov_len));
COMPILER_CHECK(sizeof(struct __sanitizer_msghdr) == sizeof(struct msghdr));
COMPILER_CHECK(offsetof(struct __sanitizer_msghdr, msg_name) ==
offsetof(struct msghdr, msg_name));
COMPILER_CHECK(offsetof(struct __sanitizer_msghdr, msg_namelen) ==
offsetof(struct msghdr, msg_namelen));
COMPILER_CHECK(offsetof(struct __sanitizer_msghdr, msg_iov) ==
offsetof(struct msghdr, msg_iov));
COMPILER_CHECK(offsetof(struct __sanitizer_msghdr, msg_iovlen) ==
offsetof(struct msghdr, msg_iovlen));
COMPILER_CHECK(offsetof(struct __sanitizer_msghdr, msg_control) ==
offsetof(struct msghdr, msg_control));
COMPILER_CHECK(offsetof(struct __sanitizer_msghdr, msg_controllen) ==
offsetof(struct msghdr, msg_controllen));
COMPILER_CHECK(offsetof(struct __sanitizer_msghdr, msg_flags) ==
offsetof(struct msghdr, msg_flags));
COMPILER_CHECK(sizeof(struct __sanitizer_cmsghdr) == sizeof(struct cmsghdr));
COMPILER_CHECK(offsetof(struct __sanitizer_cmsghdr, cmsg_len) ==
offsetof(struct cmsghdr, cmsg_len));
COMPILER_CHECK(offsetof(struct __sanitizer_cmsghdr, cmsg_level) ==
offsetof(struct cmsghdr, cmsg_level));
COMPILER_CHECK(offsetof(struct __sanitizer_cmsghdr, cmsg_type) ==
offsetof(struct cmsghdr, cmsg_type));
#endif // SANITIZER_LINUX || SANITIZER_MAC

View File

@ -49,10 +49,26 @@ namespace __sanitizer {
extern unsigned struct_statfs64_sz;
#endif // SANITIZER_LINUX && !SANITIZER_ANDROID
void* __sanitizer_get_msghdr_iov_iov_base(void* msg, int idx);
uptr __sanitizer_get_msghdr_iov_iov_len(void* msg, int idx);
uptr __sanitizer_get_msghdr_iovlen(void* msg);
uptr __sanitizer_get_socklen_t(void* socklen_ptr);
struct __sanitizer_iovec {
void *iov_base;
uptr iov_len;
};
struct __sanitizer_msghdr {
void *msg_name;
unsigned msg_namelen;
struct __sanitizer_iovec *msg_iov;
uptr msg_iovlen;
void *msg_control;
uptr msg_controllen;
int msg_flags;
};
struct __sanitizer_cmsghdr {
uptr cmsg_len;
int cmsg_level;
int cmsg_type;
};
// This thing depends on the platform. We are only interested in the upper
// limit. Verified with a compiler assert in .cc.

View File

@ -1509,15 +1509,6 @@ TSAN_INTERCEPTOR(long_t, recv, int fd, void *buf, long_t len, int flags) {
return res;
}
TSAN_INTERCEPTOR(long_t, recvmsg, int fd, void *msg, int flags) {
SCOPED_TSAN_INTERCEPTOR(recvmsg, fd, msg, flags);
int res = REAL(recvmsg)(fd, msg, flags);
if (res >= 0 && fd >= 0) {
FdAcquire(thr, pc, fd);
}
return res;
}
TSAN_INTERCEPTOR(int, unlink, char *path) {
SCOPED_TSAN_INTERCEPTOR(unlink, path);
Release(thr, pc, File2addr(path));
@ -2063,7 +2054,6 @@ void InitializeInterceptors() {
TSAN_INTERCEPT(send);
TSAN_INTERCEPT(sendmsg);
TSAN_INTERCEPT(recv);
TSAN_INTERCEPT(recvmsg);
TSAN_INTERCEPT(unlink);
TSAN_INTERCEPT(fopen);