[compiler-rt] r261841 - [sanitizer] Move recvmsg and recv interceptors to sanitizer_common.

Maxim Ostapenko via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 25 00:44:27 PST 2016


Author: chefmax
Date: Thu Feb 25 02:44:25 2016
New Revision: 261841

URL: http://llvm.org/viewvc/llvm-project?rev=261841&view=rev
Log:
[sanitizer] Move recvmsg and recv interceptors to sanitizer_common.

This patch moves recv and recvfrom interceptors from MSan and TSan to
sanitizer_common to enable them in ASan.

Differential Revision: http://reviews.llvm.org/D17479

Added:
    compiler-rt/trunk/test/asan/TestCases/Linux/recvfrom.cc
Modified:
    compiler-rt/trunk/lib/msan/msan_interceptors.cc
    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

Modified: compiler-rt/trunk/lib/msan/msan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_interceptors.cc?rev=261841&r1=261840&r2=261841&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Thu Feb 25 02:44:25 2016
@@ -978,30 +978,6 @@ INTERCEPTOR(int, epoll_pwait, int epfd,
 #define MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT
 #endif
 
-INTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) {
-  ENSURE_MSAN_INITED();
-  SSIZE_T res = REAL(recv)(fd, buf, len, flags);
-  if (res > 0)
-    __msan_unpoison(buf, res);
-  return res;
-}
-
-INTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags,
-            void *srcaddr, int *addrlen) {
-  ENSURE_MSAN_INITED();
-  SIZE_T srcaddr_sz;
-  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 = *addrlen;
-      __msan_unpoison(srcaddr, Min(sz, srcaddr_sz));
-    }
-  }
-  return res;
-}
-
 INTERCEPTOR(void *, calloc, SIZE_T nmemb, SIZE_T size) {
   GET_MALLOC_STACK_TRACE;
   if (UNLIKELY(!msan_inited)) {
@@ -1647,8 +1623,6 @@ void InitializeInterceptors() {
   INTERCEPT_FUNCTION(gethostname);
   MSAN_MAYBE_INTERCEPT_EPOLL_WAIT;
   MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT;
-  INTERCEPT_FUNCTION(recv);
-  INTERCEPT_FUNCTION(recvfrom);
   INTERCEPT_FUNCTION(dladdr);
   INTERCEPT_FUNCTION(dlerror);
   INTERCEPT_FUNCTION(dl_iterate_phdr);

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=261841&r1=261840&r2=261841&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Thu Feb 25 02:44:25 2016
@@ -5333,6 +5333,43 @@ INTERCEPTOR(char *, ctermid_r, char *s)
 #define INIT_CTERMID_R
 #endif
 
+#if SANITIZER_INTERCEPT_RECV_RECVFROM
+INTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, recv, fd, buf, len, flags);
+  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
+  SSIZE_T res = REAL(recv)(fd, buf, len, flags);
+  if (res > 0) {
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, len);
+  }
+  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
+  return res;
+}
+
+INTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags,
+            void *srcaddr, int *addrlen) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, recvfrom, fd, buf, len, flags, srcaddr,
+                           addrlen);
+  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
+  SIZE_T srcaddr_sz;
+  if (srcaddr) srcaddr_sz = *addrlen;
+  SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen);
+  if (res > 0) {
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, len);
+    if (srcaddr)
+      COMMON_INTERCEPTOR_INITIALIZE_RANGE(srcaddr,
+                                          Min((SIZE_T)*addrlen, srcaddr_sz));
+  }
+  return res;
+}
+#define INIT_RECV_RECVFROM          \
+  COMMON_INTERCEPT_FUNCTION(recv);  \
+  COMMON_INTERCEPT_FUNCTION(recvfrom);
+#else
+#define INIT_RECV_RECVFROM
+#endif
+
 static void InitializeCommonInterceptors() {
   static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
   interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap();
@@ -5509,4 +5546,5 @@ static void InitializeCommonInterceptors
   INIT_PROCESS_VM_READV;
   INIT_CTERMID;
   INIT_CTERMID_R;
+  INIT_RECV_RECVFROM;
 }

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=261841&r1=261840&r2=261841&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h Thu Feb 25 02:44:25 2016
@@ -272,5 +272,6 @@
 #define SANITIZER_INTERCEPT_CTERMID_R SI_MAC || SI_FREEBSD
 
 #define SANITIZER_INTERCEPTOR_HOOKS SI_LINUX
+#define SANITIZER_INTERCEPT_RECV_RECVFROM 1
 
 #endif  // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H

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=261841&r1=261840&r2=261841&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Thu Feb 25 02:44:25 2016
@@ -1814,17 +1814,6 @@ TSAN_INTERCEPTOR(long_t, sendmsg, int fd
   return res;
 }
 
-TSAN_INTERCEPTOR(long_t, recv, int fd, void *buf, long_t len, int flags) {
-  SCOPED_TSAN_INTERCEPTOR(recv, fd, buf, len, flags);
-  if (fd >= 0)
-    FdAccess(thr, pc, fd);
-  int res = REAL(recv)(fd, buf, len, 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));
@@ -2716,7 +2705,6 @@ void InitializeInterceptors() {
 
   TSAN_INTERCEPT(send);
   TSAN_INTERCEPT(sendmsg);
-  TSAN_INTERCEPT(recv);
 
   TSAN_INTERCEPT(unlink);
   TSAN_INTERCEPT(tmpfile);

Added: 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=261841&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Linux/recvfrom.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/Linux/recvfrom.cc Thu Feb 25 02:44:25 2016
@@ -0,0 +1,79 @@
+// Test that ASan detects buffer overflow on read from socket via recvfrom.
+//
+// RUN: %clangxx_asan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O1 %s -o %t && not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O2 %s -o %t && not %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx_asan -O3 %s -o %t && not %run %t 2>&1 | FileCheck %s
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <pthread.h>
+
+const int kPortNum = 1234;
+const int kBufSize = 10;
+
+static void *server_thread_udp(void *data) {
+  char buf[kBufSize / 2];
+  struct sockaddr_in serveraddr; // server's addr
+  int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+  if (sockfd < 0)
+    fprintf(stderr, "ERROR opening socket\n");
+
+  memset((char *) &serveraddr, 0, sizeof(serveraddr));
+  serveraddr.sin_family = AF_INET;
+  serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
+  serveraddr.sin_port = htons(kPortNum);
+
+  if (bind(sockfd, (struct sockaddr *) &serveraddr, sizeof(serveraddr)) < 0)
+    fprintf(stderr, "ERROR on binding\n");
+
+  recvfrom(sockfd, buf, kBufSize, 0, NULL, NULL); // BOOM
+  // CHECK: {{WRITE of size 10 at 0x.* thread T1}}
+  // CHECK: {{    #1 0x.* in server_thread_udp.*recvfrom.cc:}}[[@LINE-2]]
+  // CHECK: {{Address 0x.* is located in stack of thread T1 at offset}}
+  // CHECK-NEXT: in{{.*}}server_thread_udp{{.*}}recvfrom.cc
+  return NULL;
+}
+
+int main() {
+  char buf[kBufSize] = "123456789";
+  struct sockaddr_in serveraddr; // server's addr
+
+  pthread_t server_thread;
+  if (pthread_create(&server_thread, NULL, server_thread_udp, NULL)) {
+    fprintf(stderr, "Error creating thread\n");
+    exit(1);
+  }
+
+  int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+  struct hostent *server;
+  char hostname[] = "localhost";
+  if (sockfd < 0)
+    fprintf(stderr, "ERROR opening socket\n");
+
+  server = gethostbyname(hostname);
+  if (!server) {
+    fprintf(stderr,"ERROR, no such host as %s\n", hostname);
+    exit(1);
+  }
+
+  memset((char *) &serveraddr, 0, sizeof(serveraddr));
+  serveraddr.sin_family = AF_INET;
+  memcpy((char *)&serveraddr.sin_addr.s_addr, (char *)server->h_addr,
+          server->h_length);
+  serveraddr.sin_port = htons(kPortNum);
+  sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *) &serveraddr,
+         sizeof(serveraddr));
+
+  if (pthread_join(server_thread, NULL)) {
+    fprintf(stderr, "Error joining thread\n");
+    exit(1);
+  }
+
+  return 0;
+}




More information about the llvm-commits mailing list