[compiler-rt] r178465 - [sanitizer] More interceptors.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Mon Apr 1 07:47:22 PDT 2013


Author: eugenis
Date: Mon Apr  1 09:47:21 2013
New Revision: 178465

URL: http://llvm.org/viewvc/llvm-project?rev=178465&view=rev
Log:
[sanitizer] More interceptors.

getpwnam, getpwuid, getpwnam_r, getpwuid_r, clock_getres, clock_gettime,
clock_settime, getitimer, setitimer, sigaction (MSan).


Modified:
    compiler-rt/trunk/lib/msan/msan_interceptors.cc
    compiler-rt/trunk/lib/msan/tests/msan_test.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

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=178465&r1=178464&r2=178465&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Mon Apr  1 09:47:21 2013
@@ -824,6 +824,17 @@ INTERCEPTOR(int, getrusage, int who, voi
   return res;
 }
 
+INTERCEPTOR(int, sigaction, int signum, const void *act, void *oldact) {
+  ENSURE_MSAN_INITED();
+  // TODO: check that *act is unpoisoned.
+  // That requires intercepting all of sigemptyset, sigfillset, etc.
+  int res = REAL(sigaction)(signum, act, oldact);
+  if (res == 0) {
+    __msan_unpoison(oldact, __sanitizer::struct_sigaction_sz);
+  }
+  return res;
+}
+
 extern "C" int pthread_attr_init(void *attr);
 extern "C" int pthread_attr_destroy(void *attr);
 extern "C" int pthread_attr_setstacksize(void *attr, uptr stacksize);
@@ -843,6 +854,9 @@ INTERCEPTOR(int, pthread_create, void *t
   int res = REAL(pthread_create)(th, attr, callback, param);
   if (attr == &myattr)
     pthread_attr_destroy(&myattr);
+  if (!res) {
+    __msan_unpoison(th, __sanitizer::pthread_t_sz);
+  }
   return res;
 }
 
@@ -1054,6 +1068,7 @@ void InitializeInterceptors() {
   INTERCEPT_FUNCTION(dladdr);
   INTERCEPT_FUNCTION(dlopen);
   INTERCEPT_FUNCTION(getrusage);
+  INTERCEPT_FUNCTION(sigaction);
   INTERCEPT_FUNCTION(pthread_create);
   inited = 1;
 }

Modified: compiler-rt/trunk/lib/msan/tests/msan_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/tests/msan_test.cc?rev=178465&r1=178464&r2=178465&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/tests/msan_test.cc (original)
+++ compiler-rt/trunk/lib/msan/tests/msan_test.cc Mon Apr  1 09:47:21 2013
@@ -40,6 +40,7 @@
 #include <sys/vfs.h>
 #include <sys/types.h>
 #include <dirent.h>
+#include <pwd.h>
 
 #if defined(__i386__) || defined(__x86_64__)
 # include <emmintrin.h>
@@ -849,6 +850,45 @@ TEST(MemorySanitizer, gettimeofday) {
   EXPECT_NOT_POISONED(tz.tz_dsttime);
 }
 
+TEST(MemorySanitizer, clock_gettime) {
+  struct timespec tp;
+  EXPECT_POISONED(tp.tv_sec);
+  EXPECT_POISONED(tp.tv_nsec);
+  assert(0 == clock_gettime(CLOCK_REALTIME, &tp));
+  EXPECT_NOT_POISONED(tp.tv_sec);
+  EXPECT_NOT_POISONED(tp.tv_nsec);
+}
+
+TEST(MemorySanitizer, getitimer) {
+  struct itimerval it1, it2;
+  int res;
+  EXPECT_POISONED(it1.it_interval.tv_sec);
+  EXPECT_POISONED(it1.it_interval.tv_usec);
+  EXPECT_POISONED(it1.it_value.tv_sec);
+  EXPECT_POISONED(it1.it_value.tv_usec);
+  res = getitimer(ITIMER_VIRTUAL, &it1);
+  assert(!res);
+  EXPECT_NOT_POISONED(it1.it_interval.tv_sec);
+  EXPECT_NOT_POISONED(it1.it_interval.tv_usec);
+  EXPECT_NOT_POISONED(it1.it_value.tv_sec);
+  EXPECT_NOT_POISONED(it1.it_value.tv_usec);
+
+  it1.it_interval.tv_sec = it1.it_value.tv_sec = 10000;
+  it1.it_interval.tv_usec = it1.it_value.tv_usec = 0;
+
+  res = setitimer(ITIMER_VIRTUAL, &it1, &it2);
+  assert(!res);
+  EXPECT_NOT_POISONED(it2.it_interval.tv_sec);
+  EXPECT_NOT_POISONED(it2.it_interval.tv_usec);
+  EXPECT_NOT_POISONED(it2.it_value.tv_sec);
+  EXPECT_NOT_POISONED(it2.it_value.tv_usec);
+
+  // Check that old_value can be 0, and disable the timer.
+  memset(&it1, 0, sizeof(it1));
+  res = setitimer(ITIMER_VIRTUAL, &it1, 0);
+  assert(!res);
+}
+
 TEST(MemorySanitizer, localtime) {
   time_t t = 123;
   struct tm *time = localtime(&t);
@@ -1434,6 +1474,7 @@ TEST(MemorySanitizer, SimpleThread) {
   void *p;
   int res = pthread_create(&t, NULL, SimpleThread_threadfn, NULL);
   assert(!res);
+  EXPECT_NOT_POISONED(t);
   res = pthread_join(t, &p);
   assert(!res);
   if (!__msan_has_dynamic_component())  // FIXME: intercept pthread_join (?).
@@ -1500,6 +1541,40 @@ TEST(MemorySanitizer, gethostname) {
   EXPECT_NOT_POISONED(strlen(buf));
 }
 
+TEST(MemorySanitizer, getpwuid) {
+  struct passwd *p = getpwuid(0); // root
+  assert(p);
+  EXPECT_NOT_POISONED(p->pw_name);
+  assert(p->pw_name);
+  EXPECT_NOT_POISONED(p->pw_name[0]);
+  EXPECT_NOT_POISONED(p->pw_uid);
+  assert(p->pw_uid == 0);
+}
+
+TEST(MemorySanitizer, getpwnam_r) {
+  struct passwd pwd;
+  struct passwd *pwdres;
+  char buf[10000];
+  int res = getpwnam_r("root", &pwd, buf, sizeof(buf), &pwdres);
+  assert(!res);
+  EXPECT_NOT_POISONED(pwd.pw_name);
+  assert(pwd.pw_name);
+  EXPECT_NOT_POISONED(pwd.pw_name[0]);
+  EXPECT_NOT_POISONED(pwd.pw_uid);
+  assert(pwd.pw_uid == 0);
+}
+
+TEST(MemorySanitizer, getpwnam_r_positive) {
+  struct passwd pwd;
+  struct passwd *pwdres;
+  char s[5];
+  strncpy(s, "abcd", 5);
+  __msan_poison(s, 5);
+  char buf[10000];
+  int res;
+  EXPECT_UMR(res = getpwnam_r(s, &pwd, buf, sizeof(buf), &pwdres));
+}
+
 template<class T>
 static bool applySlt(T value, T shadow) {
   __msan_partial_poison(&value, &shadow, sizeof(T));

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=178465&r1=178464&r2=178465&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc Mon Apr  1 09:47:21 2013
@@ -411,6 +411,126 @@ SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf,
 #define INIT_SCANF
 #endif
 
+#if SANITIZER_INTERCEPT_GETPWNAM_GETPWUID
+INTERCEPTOR(void *, getpwnam, const char *name) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
+  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
+  void *res = REAL(getpwnam)(name);
+  if (res != 0)
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz);
+  return res;
+}
+INTERCEPTOR(void *, getpwuid, u32 uid) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
+  void *res = REAL(getpwuid)(uid);
+  if (res != 0)
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz);
+  return res;
+}
+#define INIT_GETPWNAM_GETPWUID                  \
+  INTERCEPT_FUNCTION(getpwnam);                 \
+  INTERCEPT_FUNCTION(getpwuid);
+#else
+#define INIT_GETPWNAM_GETPWUID
+#endif
+
+
+#if SANITIZER_INTERCEPT_GETPWNAM_R_GETPWUID_R
+INTERCEPTOR(int, getpwnam_r, const char *name, void *pwd,
+    char *buf, SIZE_T buflen, void **result) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
+  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
+  int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
+  if (!res) {
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz);
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
+  }
+  return res;
+}
+INTERCEPTOR(int, getpwuid_r, u32 uid, void *pwd,
+    char *buf, SIZE_T buflen, void **result) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
+  int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
+  if (!res) {
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz);
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
+  }
+  return res;
+}
+#define INIT_GETPWNAM_R_GETPWUID_R                \
+  INTERCEPT_FUNCTION(getpwnam_r);                 \
+  INTERCEPT_FUNCTION(getpwuid_r);
+#else
+#define INIT_GETPWNAM_R_GETPWUID_R
+#endif
+
+
+#if SANITIZER_INTERCEPT_CLOCK_GETTIME
+INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
+  int res = REAL(clock_getres)(clk_id, tp);
+  if (!res) {
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
+  }
+  return res;
+}
+INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
+  int res = REAL(clock_gettime)(clk_id, tp);
+  if (!res) {
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
+  }
+  return res;
+}
+INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
+  COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
+  return REAL(clock_settime)(clk_id, tp);
+}
+#define INIT_CLOCK_GETTIME                         \
+  INTERCEPT_FUNCTION(clock_getres);                \
+  INTERCEPT_FUNCTION(clock_gettime);               \
+  INTERCEPT_FUNCTION(clock_settime);
+#else
+#define INIT_CLOCK_GETTIME
+#endif
+
+
+#if SANITIZER_INTERCEPT_GETITIMER
+INTERCEPTOR(int, getitimer, int which, void *curr_value) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
+  int res = REAL(getitimer)(which, curr_value);
+  if (!res) {
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
+  }
+  return res;
+}
+INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
+  void *ctx;
+  COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
+  COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz);
+  int res = REAL(setitimer)(which, new_value, old_value);
+  if (!res && old_value) {
+    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
+  }
+  return res;
+}
+#define INIT_GETITIMER                             \
+  INTERCEPT_FUNCTION(getitimer);                   \
+  INTERCEPT_FUNCTION(setitimer);
+#else
+#define INIT_GETITIMER
+#endif
+
+
 #define SANITIZER_COMMON_INTERCEPTORS_INIT                                     \
   INIT_STRCASECMP;                                                             \
   INIT_STRNCASECMP;                                                            \
@@ -424,4 +544,8 @@ SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf,
   INIT_LOCALTIME_AND_FRIENDS;                                                  \
   INIT_SCANF;                                                                  \
   INIT_FREXP;                                                                  \
-  INIT_FREXPF_FREXPL;
+  INIT_FREXPF_FREXPL;                                                          \
+  INIT_GETPWNAM_GETPWUID;                                                      \
+  INIT_GETPWNAM_R_GETPWUID_R;                                                  \
+  INIT_CLOCK_GETTIME;                                                          \
+  INIT_GETITIMER;

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=178465&r1=178464&r2=178465&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h Mon Apr  1 09:47:21 2013
@@ -35,6 +35,12 @@
 
 # define SANITIZER_INTERCEPT_STRCASECMP SI_NOT_WINDOWS
 
+#if SANITIZER_MAC
+# define SI_MAC 1
+#else
+# define SI_MAC 0
+#endif
+
 # define SANITIZER_INTERCEPT_READ   SI_NOT_WINDOWS
 # define SANITIZER_INTERCEPT_PREAD  SI_NOT_WINDOWS
 # define SANITIZER_INTERCEPT_WRITE  SI_NOT_WINDOWS
@@ -51,3 +57,8 @@
 
 # define SANITIZER_INTERCEPT_FREXP 1
 # define SANITIZER_INTERCEPT_FREXPF_FREXPL SI_NOT_WINDOWS
+
+# define SANITIZER_INTERCEPT_GETPWNAM_GETPWUID SI_NOT_WINDOWS
+# define SANITIZER_INTERCEPT_GETPWNAM_R_GETPWUID_R SI_MAC || SI_LINUX_NOT_ANDROID
+# define SANITIZER_INTERCEPT_CLOCK_GETTIME SI_LINUX
+# define SANITIZER_INTERCEPT_GETITIMER SI_NOT_WINDOWS

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=178465&r1=178464&r2=178465&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 Mon Apr  1 09:47:21 2013
@@ -21,6 +21,8 @@
 
 #include <dirent.h>
 #include <pthread.h>
+#include <pwd.h>
+#include <signal.h>
 #include <sys/utsname.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -40,12 +42,17 @@ namespace __sanitizer {
   unsigned struct_stat64_sz = sizeof(struct stat64);
   unsigned struct_rusage_sz = sizeof(struct rusage);
   unsigned struct_tm_sz = sizeof(struct tm);
+  unsigned struct_passwd_sz = sizeof(struct passwd);
+  unsigned struct_sigaction_sz = sizeof(struct sigaction);
+  unsigned struct_itimerval_sz = sizeof(struct itimerval);
+  unsigned pthread_t_sz = sizeof(pthread_t);
 
 #if SANITIZER_LINUX
   unsigned struct_rlimit_sz = sizeof(struct rlimit);
   unsigned struct_dirent_sz = sizeof(struct dirent);
   unsigned struct_statfs_sz = sizeof(struct statfs);
   unsigned struct_epoll_event_sz = sizeof(struct epoll_event);
+  unsigned struct_timespec_sz = sizeof(struct timespec);
 #endif // __linux__
 
 #if SANITIZER_LINUX && !SANITIZER_ANDROID

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=178465&r1=178464&r2=178465&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 Mon Apr  1 09:47:21 2013
@@ -23,12 +23,17 @@ namespace __sanitizer {
   extern unsigned struct_stat64_sz;
   extern unsigned struct_rusage_sz;
   extern unsigned struct_tm_sz;
+  extern unsigned struct_passwd_sz;
+  extern unsigned struct_sigaction_sz;
+  extern unsigned struct_itimerval_sz;
+  extern unsigned pthread_t_sz;
 
 #if SANITIZER_LINUX
   extern unsigned struct_rlimit_sz;
   extern unsigned struct_dirent_sz;
   extern unsigned struct_statfs_sz;
   extern unsigned struct_epoll_event_sz;
+  extern unsigned struct_timespec_sz;
 #endif // __linux__
 
 #if SANITIZER_LINUX && !SANITIZER_ANDROID

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=178465&r1=178464&r2=178465&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_stat.cc Mon Apr  1 09:47:21 2013
@@ -287,6 +287,15 @@ void StatOutput(u64 *stat) {
   name[StatInt_frexp]                    = "  frexp                           ";
   name[StatInt_frexpf]                   = "  frexpf                          ";
   name[StatInt_frexpl]                   = "  frexpl                          ";
+  name[StatInt_getpwnam]                 = "  getpwnam                        ";
+  name[StatInt_getpwuid]                 = "  getpwuid                        ";
+  name[StatInt_getpwnam_r]               = "  getpwnam_r                      ";
+  name[StatInt_getpwuid_r]               = "  getpwuid_r                      ";
+  name[StatInt_clock_getres]             = "  clock_getres                    ";
+  name[StatInt_clock_gettime]            = "  clock_gettime                   ";
+  name[StatInt_clock_settime]            = "  clock_settime                   ";
+  name[StatInt_getitimer]                = "  getitimer                       ";
+  name[StatInt_setitimer]                = "  setitimer                       ";
 
   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=178465&r1=178464&r2=178465&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_stat.h Mon Apr  1 09:47:21 2013
@@ -282,6 +282,15 @@ enum StatType {
   StatInt_frexp,
   StatInt_frexpf,
   StatInt_frexpl,
+  StatInt_getpwnam,
+  StatInt_getpwuid,
+  StatInt_getpwnam_r,
+  StatInt_getpwuid_r,
+  StatInt_clock_getres,
+  StatInt_clock_gettime,
+  StatInt_clock_settime,
+  StatInt_getitimer,
+  StatInt_setitimer,
 
   // Dynamic annotations.
   StatAnnotation,





More information about the llvm-commits mailing list