[compiler-rt] r272980 - [msan] Intercept send/sendto/sendmsg.
Evgeniy Stepanov via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 16 17:43:12 PDT 2016
Author: eugenis
Date: Thu Jun 16 19:43:11 2016
New Revision: 272980
URL: http://llvm.org/viewvc/llvm-project?rev=272980&view=rev
Log:
[msan] Intercept send/sendto/sendmsg.
send/sendmsg moved from tsan to sanitizer_common; sendto is new.
Added:
compiler-rt/trunk/test/msan/Linux/sendmsg.cc
Modified:
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
compiler-rt/trunk/test/asan/TestCases/Linux/recvfrom.cc
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc?rev=272980&r1=272979&r2=272980&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Thu Jun 16 19:43:11 2016
@@ -2498,6 +2498,37 @@ INTERCEPTOR(SSIZE_T, recvmsg, int fd, st
#define INIT_RECVMSG
#endif
+#if SANITIZER_INTERCEPT_SENDMSG
+static void read_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
+ SSIZE_T maxlen) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, msg, sizeof(*msg));
+ if (msg->msg_name && msg->msg_namelen)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_name, msg->msg_namelen);
+ if (msg->msg_iov && msg->msg_iovlen)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_iov,
+ sizeof(*msg->msg_iov) * msg->msg_iovlen);
+ read_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
+ if (msg->msg_control && msg->msg_controllen)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_control, msg->msg_controllen);
+}
+
+INTERCEPTOR(SSIZE_T, sendmsg, int fd, struct __sanitizer_msghdr *msg,
+ int flags) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, sendmsg, fd, msg, flags);
+ if (fd >= 0) {
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
+ COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
+ }
+ SSIZE_T res = REAL(sendmsg)(fd, msg, flags);
+ if (res >= 0 && msg) read_msghdr(ctx, msg, res);
+ return res;
+}
+#define INIT_SENDMSG COMMON_INTERCEPT_FUNCTION(sendmsg);
+#else
+#define INIT_SENDMSG
+#endif
+
#if SANITIZER_INTERCEPT_GETPEERNAME
INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {
void *ctx;
@@ -5529,6 +5560,39 @@ INTERCEPTOR(SSIZE_T, recvfrom, int fd, v
#define INIT_RECV_RECVFROM
#endif
+#if SANITIZER_INTERCEPT_SEND_SENDTO
+INTERCEPTOR(SSIZE_T, send, int fd, void *buf, SIZE_T len, int flags) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, send, fd, buf, len, flags);
+ if (fd >= 0) {
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
+ COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
+ }
+ SSIZE_T res = REAL(send)(fd, buf, len, flags);
+ if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));
+ return res;
+}
+
+INTERCEPTOR(SSIZE_T, sendto, int fd, void *buf, SIZE_T len, int flags,
+ void *srcaddr, int addrlen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, sendto, fd, buf, len, flags, srcaddr, addrlen);
+ if (fd >= 0) {
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
+ COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
+ }
+ if (srcaddr && addrlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, srcaddr, addrlen);
+ SSIZE_T res = REAL(sendto)(fd, buf, len, flags, srcaddr, addrlen);
+ if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));
+ return res;
+}
+#define INIT_SEND_SENDTO \
+ COMMON_INTERCEPT_FUNCTION(send); \
+ COMMON_INTERCEPT_FUNCTION(sendto);
+#else
+#define INIT_SEND_SENDTO
+#endif
+
#if SANITIZER_INTERCEPT_STAT
INTERCEPTOR(int, stat, const char *path, void *buf) {
void *ctx;
@@ -5684,6 +5748,7 @@ static void InitializeCommonInterceptors
INIT_ACCEPT4;
INIT_MODF;
INIT_RECVMSG;
+ INIT_SENDMSG;
INIT_GETPEERNAME;
INIT_IOCTL;
INIT_INET_ATON;
@@ -5796,6 +5861,7 @@ static void InitializeCommonInterceptors
INIT_CTERMID;
INIT_CTERMID_R;
INIT_RECV_RECVFROM;
+ INIT_SEND_SENDTO;
INIT_STAT;
INIT___XSTAT;
INIT___XSTAT64;
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h?rev=272980&r1=272979&r2=272980&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h Thu Jun 16 19:43:11 2016
@@ -155,6 +155,7 @@
#define SANITIZER_INTERCEPT_ACCEPT4 SI_LINUX_NOT_ANDROID
#define SANITIZER_INTERCEPT_MODF SI_NOT_WINDOWS
#define SANITIZER_INTERCEPT_RECVMSG SI_NOT_WINDOWS
+#define SANITIZER_INTERCEPT_SENDMSG SI_NOT_WINDOWS
#define SANITIZER_INTERCEPT_GETPEERNAME SI_NOT_WINDOWS
#define SANITIZER_INTERCEPT_IOCTL SI_NOT_WINDOWS
#define SANITIZER_INTERCEPT_INET_ATON SI_NOT_WINDOWS
@@ -308,6 +309,7 @@
#define SANITIZER_INTERCEPTOR_HOOKS SI_LINUX
#define SANITIZER_INTERCEPT_RECV_RECVFROM SI_NOT_WINDOWS
+#define SANITIZER_INTERCEPT_SEND_SENDTO SI_NOT_WINDOWS
#define SANITIZER_INTERCEPT_STAT (SI_FREEBSD || SI_MAC || SI_ANDROID)
#define SANITIZER_INTERCEPT___XSTAT !SANITIZER_INTERCEPT_STAT && SI_NOT_WINDOWS
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc?rev=272980&r1=272979&r2=272980&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Thu Jun 16 19:43:11 2016
@@ -1615,26 +1615,6 @@ TSAN_INTERCEPTOR(int, pipe2, int *pipefd
}
#endif
-TSAN_INTERCEPTOR(long_t, send, int fd, void *buf, long_t len, int flags) {
- SCOPED_TSAN_INTERCEPTOR(send, fd, buf, len, flags);
- if (fd >= 0) {
- FdAccess(thr, pc, fd);
- FdRelease(thr, pc, fd);
- }
- int res = REAL(send)(fd, buf, len, flags);
- return res;
-}
-
-TSAN_INTERCEPTOR(long_t, sendmsg, int fd, void *msg, int flags) {
- SCOPED_TSAN_INTERCEPTOR(sendmsg, fd, msg, flags);
- if (fd >= 0) {
- FdAccess(thr, pc, fd);
- FdRelease(thr, pc, fd);
- }
- int res = REAL(sendmsg)(fd, msg, flags);
- return res;
-}
-
TSAN_INTERCEPTOR(int, unlink, char *path) {
SCOPED_TSAN_INTERCEPTOR(unlink, path);
Release(thr, pc, File2addr(path));
@@ -2560,9 +2540,6 @@ void InitializeInterceptors() {
TSAN_INTERCEPT(pipe);
TSAN_INTERCEPT(pipe2);
- TSAN_INTERCEPT(send);
- TSAN_INTERCEPT(sendmsg);
-
TSAN_INTERCEPT(unlink);
TSAN_INTERCEPT(tmpfile);
TSAN_MAYBE_INTERCEPT_TMPFILE64;
Modified: compiler-rt/trunk/test/asan/TestCases/Linux/recvfrom.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/recvfrom.cc?rev=272980&r1=272979&r2=272980&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Linux/recvfrom.cc (original)
+++ compiler-rt/trunk/test/asan/TestCases/Linux/recvfrom.cc Thu Jun 16 19:43:11 2016
@@ -1,6 +1,7 @@
// Test that ASan detects buffer overflow on read from socket via recvfrom.
//
-// RUN: %clangxx_asan %s -o %t && not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan %s -DRECVFROM -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-RECVFROM
+// RUN: %clangxx_asan %s -DSENDTO -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-SENDTO
//
// UNSUPPORTED: android
@@ -25,21 +26,31 @@ const int kBufSize = 10;
int sockfd;
static void *client_thread_udp(void *data) {
+#ifdef SENDTO
+ const char buf[kBufSize / 2] = {0, };
+#else
const char buf[kBufSize] = {0, };
+#endif
struct sockaddr_in serveraddr;
socklen_t addrlen = sizeof(serveraddr);
int succeeded = getsockname(sockfd, (struct sockaddr *)&serveraddr, &addrlen);
CHECK_ERROR(succeeded < 0, "in getsockname");
- succeeded = sendto(sockfd, buf, kBufSize, 0,
- (struct sockaddr *)&serveraddr, sizeof(serveraddr));
+ succeeded = sendto(sockfd, buf, kBufSize, 0, (struct sockaddr *)&serveraddr,
+ sizeof(serveraddr));
+ // CHECK-SENDTO: {{READ of size 10 at 0x.* thread T1}}
+ // CHECK-SENDTO: {{ #1 0x.* in client_thread_udp.*recvfrom.cc:}}[[@LINE-3]]
CHECK_ERROR(succeeded < 0, "in sending message");
return NULL;
}
int main() {
+#ifdef RECVFROM
char buf[kBufSize / 2];
+#else
+ char buf[kBufSize];
+#endif
pthread_t client_thread;
struct sockaddr_in serveraddr;
@@ -59,10 +70,10 @@ int main() {
CHECK_ERROR(succeeded, "creating thread");
recvfrom(sockfd, buf, kBufSize, 0, NULL, NULL); // BOOM
- // CHECK: {{WRITE of size 10 at 0x.* thread T0}}
- // CHECK: {{ #1 0x.* in main.*recvfrom.cc:}}[[@LINE-2]]
- // CHECK: {{Address 0x.* is located in stack of thread T0 at offset}}
- // CHECK-NEXT: in{{.*}}main{{.*}}recvfrom.cc
+ // CHECK-RECVFROM: {{WRITE of size 10 at 0x.* thread T0}}
+ // CHECK-RECVFROM: {{ #1 0x.* in main.*recvfrom.cc:}}[[@LINE-2]]
+ // CHECK-RECVFROM: {{Address 0x.* is located in stack of thread T0 at offset}}
+ // CHECK-RECVFROM-NEXT: in{{.*}}main{{.*}}recvfrom.cc
succeeded = pthread_join(client_thread, NULL);
CHECK_ERROR(succeeded, "joining thread");
return 0;
Added: compiler-rt/trunk/test/msan/Linux/sendmsg.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/msan/Linux/sendmsg.cc?rev=272980&view=auto
==============================================================================
--- compiler-rt/trunk/test/msan/Linux/sendmsg.cc (added)
+++ compiler-rt/trunk/test/msan/Linux/sendmsg.cc Thu Jun 16 19:43:11 2016
@@ -0,0 +1,83 @@
+// RUN: %clangxx_msan %s -DSEND -DBUF -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SEND
+// RUN: %clangxx_msan %s -DSENDTO -DBUF -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SENDTO
+// RUN: %clangxx_msan %s -DSENDMSG -DBUF -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SENDMSG
+
+// FIXME: intercept connect() and add a SEND+ADDR test
+// RUN: %clangxx_msan %s -DSENDTO -DADDR -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SENDTO-ADDR
+// RUN: %clangxx_msan %s -DSENDMSG -DADDR -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=SENDMSG-ADDR
+
+// RUN: %clangxx_msan %s -DSEND -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=NEGATIVE
+// RUN: %clangxx_msan %s -DSENDTO -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=NEGATIVE
+// RUN: %clangxx_msan %s -DSENDMSG -o %t && %run %t 2>&1 | FileCheck %s --check-prefix=NEGATIVE
+
+// UNSUPPORTED: android
+
+#include <assert.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sanitizer/msan_interface.h>
+
+const int kBufSize = 10;
+int sockfd;
+
+int main() {
+ int ret;
+ char buf[kBufSize] = {0};
+ pthread_t client_thread;
+ struct sockaddr_in serveraddr;
+
+ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+
+ memset(&serveraddr, 0, sizeof(serveraddr));
+ serveraddr.sin_family = AF_INET;
+ serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ serveraddr.sin_port = 0;
+
+ bind(sockfd, (struct sockaddr *)&serveraddr, sizeof(serveraddr));
+ socklen_t addrlen = sizeof(serveraddr);
+ getsockname(sockfd, (struct sockaddr *)&serveraddr, &addrlen);
+
+#if defined(ADDR)
+ assert(addrlen > 3);
+ __msan_poison(((char *)&serveraddr) + 3, 1);
+#elif defined(BUF)
+ __msan_poison(buf + 7, 1);
+#endif
+
+#if defined(SENDMSG)
+ struct iovec iov[2] = {{buf, 5}, {buf + 5, 5}};
+ struct msghdr msg;
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_name = &serveraddr;
+ msg.msg_namelen = addrlen;
+ msg.msg_iov = iov;
+ msg.msg_iovlen = 2;
+#endif
+
+#if defined(SEND)
+ ret = connect(sockfd, (struct sockaddr *)&serveraddr, addrlen);
+ assert(ret == 0);
+ ret = send(sockfd, buf, kBufSize, 0);
+ // SEND: Uninitialized bytes in __interceptor_send at offset 7 inside [{{.*}}, 10)
+ assert(ret > 0);
+#elif defined(SENDTO)
+ ret =
+ sendto(sockfd, buf, kBufSize, 0, (struct sockaddr *)&serveraddr, addrlen);
+ // SENDTO: Uninitialized bytes in __interceptor_sendto at offset 7 inside [{{.*}}, 10)
+ // SENDTO-ADDR: Uninitialized bytes in __interceptor_sendto at offset 3 inside [{{.*}},
+ assert(ret > 0);
+#elif defined(SENDMSG)
+ ret = sendmsg(sockfd, &msg, 0);
+ // SENDMSG: Uninitialized bytes in {{.*}} at offset 2 inside [{{.*}}, 5)
+ // SENDMSG-ADDR: Uninitialized bytes in {{.*}} at offset 3 inside [{{.*}},
+ assert(ret > 0);
+#endif
+ fprintf(stderr, "== done\n");
+ // NEGATIVE: == done
+ return 0;
+}
More information about the llvm-commits
mailing list