[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