[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