[compiler-rt] r182466 - [msan] getaddrinfo & nested interceptor support.
Evgeniy Stepanov
eugeni.stepanov at gmail.com
Wed May 22 05:50:27 PDT 2013
Author: eugenis
Date: Wed May 22 07:50:26 2013
New Revision: 182466
URL: http://llvm.org/viewvc/llvm-project?rev=182466&view=rev
Log:
[msan] getaddrinfo & nested interceptor support.
Multiple connected changes:
- Ignore reads from nested interceptors.
- Check shadow on reads from common interceptors.
- getaddrinfo interceptor.
Added:
compiler-rt/trunk/lib/msan/lit_tests/getaddrinfo-positive.cc (with props)
compiler-rt/trunk/lib/msan/lit_tests/getaddrinfo.cc (with props)
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/sanitizer_common/sanitizer_platform_limits_posix.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h
compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc
compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h
Added: compiler-rt/trunk/lib/msan/lit_tests/getaddrinfo-positive.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/lit_tests/getaddrinfo-positive.cc?rev=182466&view=auto
==============================================================================
--- compiler-rt/trunk/lib/msan/lit_tests/getaddrinfo-positive.cc (added)
+++ compiler-rt/trunk/lib/msan/lit_tests/getaddrinfo-positive.cc Wed May 22 07:50:26 2013
@@ -0,0 +1,19 @@
+// RUN: %clangxx_msan -m64 -O0 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+// RUN: %clangxx_msan -m64 -O3 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdlib.h>
+
+int main(void) {
+ struct addrinfo *ai;
+ struct addrinfo hint;
+ int res = getaddrinfo("localhost", NULL, &hint, &ai);
+ // CHECK: UMR in __interceptor_getaddrinfo at offset 0 inside
+ // CHECK: WARNING: Use of uninitialized value
+ // CHECK: #0 {{.*}} in main {{.*}}getaddrinfo-positive.cc:[[@LINE-3]]
+ return 0;
+}
Propchange: compiler-rt/trunk/lib/msan/lit_tests/getaddrinfo-positive.cc
------------------------------------------------------------------------------
svn:eol-style = LF
Added: compiler-rt/trunk/lib/msan/lit_tests/getaddrinfo.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/lit_tests/getaddrinfo.cc?rev=182466&view=auto
==============================================================================
--- compiler-rt/trunk/lib/msan/lit_tests/getaddrinfo.cc (added)
+++ compiler-rt/trunk/lib/msan/lit_tests/getaddrinfo.cc Wed May 22 07:50:26 2013
@@ -0,0 +1,24 @@
+// RUN: %clangxx_msan -m64 -O0 %s -o %t && %t
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdlib.h>
+
+void poison_stack_ahead() {
+ char buf[100000];
+ // With -O0 this poisons a large chunk of stack.
+}
+
+int main(void) {
+ poison_stack_ahead();
+
+ struct addrinfo *ai;
+
+ // This should trigger loading of libnss_dns and friends.
+ // Those libraries are typically uninstrumented.They will call strlen() on a
+ // stack-allocated buffer, which is very likely to be poisoned. Test that we
+ // don't report this as an UMR.
+ int res = getaddrinfo("not-in-etc-hosts", NULL, NULL, &ai);
+ return 0;
+}
Propchange: compiler-rt/trunk/lib/msan/lit_tests/getaddrinfo.cc
------------------------------------------------------------------------------
svn:eol-style = LF
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=182466&r1=182465&r2=182466&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Wed May 22 07:50:26 2013
@@ -32,6 +32,18 @@ extern "C" const int __msan_keep_going;
using namespace __msan;
+// True if this is a nested interceptor.
+static THREADLOCAL int in_interceptor_scope;
+
+struct InterceptorScope {
+ InterceptorScope() { ++in_interceptor_scope; }
+ ~InterceptorScope() { --in_interceptor_scope; }
+};
+
+bool IsInInterceptorScope() {
+ return in_interceptor_scope;
+}
+
#define ENSURE_MSAN_INITED() do { \
CHECK(!msan_init_is_running); \
if (!msan_inited) { \
@@ -39,24 +51,30 @@ using namespace __msan;
} \
} while (0)
-#define CHECK_UNPOISONED(x, n) \
- do { \
- sptr offset = __msan_test_shadow(x, n); \
- if (__msan::IsInSymbolizer()) break; \
- if (offset >= 0 && __msan::flags()->report_umrs) { \
- GET_CALLER_PC_BP_SP; \
- (void)sp; \
- Printf("UMR in %s at offset %d inside [%p, +%d) \n", \
- __FUNCTION__, offset, x, n); \
- __msan::PrintWarningWithOrigin( \
- pc, bp, __msan_get_origin((char*)x + offset)); \
- if (!__msan_keep_going) { \
- Printf("Exiting\n"); \
- Die(); \
- } \
- } \
+// Check that [x, x+n) range is unpoisoned.
+#define CHECK_UNPOISONED_0(x, n) \
+ do { \
+ sptr offset = __msan_test_shadow(x, n); \
+ if (__msan::IsInSymbolizer()) break; \
+ if (offset >= 0 && __msan::flags()->report_umrs) { \
+ GET_CALLER_PC_BP_SP; \
+ (void) sp; \
+ Printf("UMR in %s at offset %d inside [%p, +%d) \n", __FUNCTION__, \
+ offset, x, n); \
+ __msan::PrintWarningWithOrigin(pc, bp, \
+ __msan_get_origin((char *) x + offset)); \
+ if (!__msan_keep_going) { \
+ Printf("Exiting\n"); \
+ Die(); \
+ } \
+ } \
} while (0)
+// Check that [x, x+n) range is unpoisoned unless we are in a nested
+// interceptor.
+#define CHECK_UNPOISONED(x, n) \
+ if (!IsInInterceptorScope()) CHECK_UNPOISONED_0(x, n);
+
static void *fast_memset(void *ptr, int c, SIZE_T n);
static void *fast_memcpy(void *dst, const void *src, SIZE_T n);
@@ -953,18 +971,28 @@ INTERCEPTOR(int, pthread_create, void *t
return res;
}
+struct MSanInterceptorContext {
+ bool in_interceptor_scope;
+};
+
+// A version of CHECK_UNPOISED using a saved scope value. Used in common interceptors.
+#define CHECK_UNPOISONED_CTX(ctx, x, n) \
+ if (!((MSanInterceptorContext *) ctx)->in_interceptor_scope) \
+ CHECK_UNPOISONED_0(x, n);
+
#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
- __msan_unpoison(ptr, size)
-#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) do { } while (false)
-#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
- do { \
- if (msan_init_is_running) \
- return REAL(func)(__VA_ARGS__); \
- ctx = 0; \
- (void)ctx; \
- ENSURE_MSAN_INITED(); \
+ __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; \
+ ENSURE_MSAN_INITED();
+#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
+ 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) \
do { } while (false) // FIXME
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=182466&r1=182465&r2=182466&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Wed May 22 07:50:26 2013
@@ -748,6 +748,38 @@ INTERCEPTOR(int, pthread_getschedparam,
#define INIT_PTHREAD_GETSCHEDPARAM
#endif
+#if SANITIZER_INTERCEPT_GETADDRINFO
+INTERCEPTOR(int, getaddrinfo, char *node, char *service,
+ struct __sanitizer_addrinfo *hints,
+ struct __sanitizer_addrinfo **out) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
+ if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1);
+ if (service)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1);
+ if (hints)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
+ int res = REAL(getaddrinfo)(node, service, hints, out);
+ if (res == 0) {
+ struct __sanitizer_addrinfo *p = *out;
+ while (p) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_addrinfo));
+ if (p->ai_addr)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, struct_sockaddr_sz);
+ if (p->ai_canonname)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
+ REAL(strlen)(p->ai_canonname) + 1);
+ p = p->ai_next;
+ }
+ }
+ return res;
+}
+#define INIT_GETADDRINFO INTERCEPT_FUNCTION(getaddrinfo);
+#else
+#define INIT_GETADDRINFO
+#endif
+
+
#define SANITIZER_COMMON_INTERCEPTORS_INIT \
INIT_STRCASECMP; \
INIT_STRNCASECMP; \
@@ -770,4 +802,5 @@ INTERCEPTOR(int, pthread_getschedparam,
INIT_GLOB; \
INIT_WAIT; \
INIT_INET; \
- INIT_PTHREAD_GETSCHEDPARAM;
+ INIT_PTHREAD_GETSCHEDPARAM; \
+ INIT_GETADDRINFO;
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=182466&r1=182465&r2=182466&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h Wed May 22 07:50:26 2013
@@ -70,5 +70,6 @@
# define SANITIZER_INTERCEPT_WAIT SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_INET SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM SI_NOT_WINDOWS
+# define SANITIZER_INTERCEPT_GETADDRINFO SI_NOT_WINDOWS
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.cc?rev=182466&r1=182465&r2=182466&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.cc Wed May 22 07:50:26 2013
@@ -29,9 +29,11 @@
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/socket.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/socket.h>
+#include <netdb.h>
#include <time.h>
#if !SANITIZER_ANDROID
@@ -56,6 +58,7 @@ namespace __sanitizer {
unsigned struct_sigaction_sz = sizeof(struct sigaction);
unsigned struct_itimerval_sz = sizeof(struct itimerval);
unsigned pthread_t_sz = sizeof(pthread_t);
+ unsigned struct_sockaddr_sz = sizeof(struct sockaddr);
#if !SANITIZER_ANDROID
unsigned ucontext_t_sz = sizeof(ucontext_t);
@@ -133,4 +136,12 @@ COMPILER_CHECK(offsetof(struct __sanitiz
offsetof(struct dl_phdr_info, dlpi_phnum));
#endif
+COMPILER_CHECK(sizeof(struct __sanitizer_addrinfo) == sizeof(struct addrinfo));
+COMPILER_CHECK(offsetof(struct __sanitizer_addrinfo, ai_addr) ==
+ offsetof(struct addrinfo, ai_addr));
+COMPILER_CHECK(offsetof(struct __sanitizer_addrinfo, ai_canonname) ==
+ offsetof(struct addrinfo, ai_canonname));
+COMPILER_CHECK(offsetof(struct __sanitizer_addrinfo, ai_next) ==
+ offsetof(struct addrinfo, ai_next));
+
#endif // SANITIZER_LINUX || SANITIZER_MAC
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h?rev=182466&r1=182465&r2=182466&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_limits_posix.h Wed May 22 07:50:26 2013
@@ -29,6 +29,7 @@ namespace __sanitizer {
extern unsigned siginfo_t_sz;
extern unsigned struct_itimerval_sz;
extern unsigned pthread_t_sz;
+ extern unsigned struct_sockaddr_sz;
#if !SANITIZER_ANDROID
extern unsigned ucontext_t_sz;
@@ -83,6 +84,17 @@ namespace __sanitizer {
short dlpi_phnum;
};
#endif
+
+ struct __sanitizer_addrinfo {
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ uptr ai_addrlen;
+ void *ai_addr;
+ char *ai_canonname;
+ struct __sanitizer_addrinfo *ai_next;
+ };
} // namespace __sanitizer
#endif
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc?rev=182466&r1=182465&r2=182466&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc Wed May 22 07:50:26 2013
@@ -311,6 +311,7 @@ void StatOutput(u64 *stat) {
name[StatInt_wait4] = " wait4 ";
name[StatInt_inet_ntop] = " inet_ntop ";
name[StatInt_inet_pton] = " inet_pton ";
+ name[StatInt_getaddrinfo] = " getaddrinfo ";
name[StatAnnotation] = "Dynamic annotations ";
name[StatAnnotateHappensBefore] = " HappensBefore ";
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h?rev=182466&r1=182465&r2=182466&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h Wed May 22 07:50:26 2013
@@ -306,6 +306,7 @@ enum StatType {
StatInt_wait4,
StatInt_inet_ntop,
StatInt_inet_pton,
+ StatInt_getaddrinfo,
// Dynamic annotations.
StatAnnotation,
More information about the llvm-commits
mailing list