diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-06-26 15:00:53 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-06-26 15:00:53 +0000 |
commit | b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4 (patch) | |
tree | 6639f74e4125b99260e63742df09df8c358cc64f /lib | |
parent | 7a0bba457ee05ced3adf37a0c0790d0ed23a5446 (diff) | |
download | compiler-rt-b5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4.tar.gz |
[sanitizer] readdir and readdir_r interceptors.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@184950 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/msan/msan_interceptors.cc | 16 | ||||
-rw-r--r-- | lib/msan/tests/msan_test.cc | 11 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_common_interceptors.inc | 64 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_interceptors.h | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_limits_posix.cc | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_limits_posix.h | 2 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_stat.cc | 4 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_stat.h | 4 |
8 files changed, 86 insertions, 19 deletions
diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc index 133bc609f..df45ca207 100644 --- a/lib/msan/msan_interceptors.cc +++ b/lib/msan/msan_interceptors.cc @@ -101,20 +101,6 @@ INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) { return res; } -INTERCEPTOR(void *, readdir, void *a) { - ENSURE_MSAN_INITED(); - void *res = REAL(readdir)(a); - __msan_unpoison(res, __sanitizer::struct_dirent_sz); - return res; -} - -INTERCEPTOR(void *, readdir64, void *a) { - ENSURE_MSAN_INITED(); - void *res = REAL(readdir)(a); - __msan_unpoison(res, __sanitizer::struct_dirent64_sz); - return res; -} - INTERCEPTOR(void *, memcpy, void *dest, const void *src, SIZE_T n) { return __msan_memcpy(dest, src, n); } @@ -1138,8 +1124,6 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(fread); INTERCEPT_FUNCTION(fread_unlocked); INTERCEPT_FUNCTION(readlink); - INTERCEPT_FUNCTION(readdir); - INTERCEPT_FUNCTION(readdir64); INTERCEPT_FUNCTION(memcpy); INTERCEPT_FUNCTION(memset); INTERCEPT_FUNCTION(memmove); diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc index 64bc74cd3..f95fe304d 100644 --- a/lib/msan/tests/msan_test.cc +++ b/lib/msan/tests/msan_test.cc @@ -889,6 +889,17 @@ TEST(MemorySanitizer, readdir) { closedir(dir); } +TEST(MemorySanitizer, readdir_r) { + DIR *dir = opendir("."); + struct dirent d; + struct dirent *pd; + int res = readdir_r(dir, &d, &pd); + assert(!res); + EXPECT_NOT_POISONED(pd); + EXPECT_NOT_POISONED(d.d_name[0]); + closedir(dir); +} + TEST(MemorySanitizer, realpath) { const char* relpath = "."; char path[PATH_MAX + 1]; diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc index 791e5dc2d..f476e1c22 100644 --- a/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -1268,6 +1268,66 @@ INTERCEPTOR(int, sysinfo, void *info) { #define INIT_SYSINFO #endif +#if SANITIZER_INTERCEPT_READDIR +INTERCEPTOR(void *, readdir, void *dirp) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp); + void *res = REAL(readdir)(dirp); + if (res) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_dirent_sz); + return res; +} + +INTERCEPTOR(int, readdir_r, void *dirp, void *entry, void **result) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result); + int res = REAL(readdir_r)(dirp, entry, result); + if (!res) { + if (result) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); + if (entry) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, entry, struct_dirent_sz); + } + return res; +} + +#define INIT_READDIR \ + INTERCEPT_FUNCTION(readdir); \ + INTERCEPT_FUNCTION(readdir_r); +#else +#define INIT_READDIR +#endif + +#if SANITIZER_INTERCEPT_READDIR64 +INTERCEPTOR(void *, readdir64, void *dirp) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp); + void *res = REAL(readdir64)(dirp); + if (res) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_dirent64_sz); + return res; +} + +INTERCEPTOR(int, readdir64_r, void *dirp, void *entry, void **result) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result); + int res = REAL(readdir64_r)(dirp, entry, result); + if (!res) { + if (result) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); + if (entry) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, entry, struct_dirent64_sz); + } + return res; +} +#define INIT_READDIR64 \ + INTERCEPT_FUNCTION(readdir64); \ + INTERCEPT_FUNCTION(readdir64_r); +#else +#define INIT_READDIR64 +#endif + + #define SANITIZER_COMMON_INTERCEPTORS_INIT \ INIT_STRCASECMP; \ INIT_STRNCASECMP; \ @@ -1309,4 +1369,6 @@ INTERCEPTOR(int, sysinfo, void *info) { INIT_GETPEERNAME; \ INIT_IOCTL; \ INIT_INET_ATON; \ - INIT_SYSINFO; + INIT_SYSINFO; \ + INIT_READDIR; \ + INIT_READDIR64; diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h index 72a0c591d..dded1eb0e 100644 --- a/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -92,5 +92,7 @@ # define SANITIZER_INTERCEPT_IOCTL SI_NOT_WINDOWS # define SANITIZER_INTERCEPT_INET_ATON SI_NOT_WINDOWS # define SANITIZER_INTERCEPT_SYSINFO SI_LINUX +# define SANITIZER_INTERCEPT_READDIR SI_NOT_WINDOWS +# define SANITIZER_INTERCEPT_READDIR64 SI_LINUX_NOT_ANDROID #endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc index 745ca3adf..79e89bbf2 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc +++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc @@ -94,6 +94,7 @@ #endif namespace __sanitizer { + unsigned struct_dirent_sz = sizeof(struct dirent); unsigned struct_utsname_sz = sizeof(struct utsname); unsigned struct_stat_sz = sizeof(struct stat); unsigned struct_stat64_sz = sizeof(struct stat64); @@ -115,7 +116,6 @@ namespace __sanitizer { #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_sysinfo_sz = sizeof(struct sysinfo); diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 85ef5f6c6..6e4c6558c 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -18,6 +18,7 @@ #include "sanitizer_platform.h" namespace __sanitizer { + extern unsigned struct_dirent_sz; extern unsigned struct_utsname_sz; extern unsigned struct_stat_sz; extern unsigned struct_stat64_sz; @@ -39,7 +40,6 @@ namespace __sanitizer { #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_sysinfo_sz; diff --git a/lib/tsan/rtl/tsan_stat.cc b/lib/tsan/rtl/tsan_stat.cc index 25737a42b..5fec1c502 100644 --- a/lib/tsan/rtl/tsan_stat.cc +++ b/lib/tsan/rtl/tsan_stat.cc @@ -331,6 +331,10 @@ void StatOutput(u64 *stat) { name[StatInt_getpeername] = " getpeername "; name[StatInt_ioctl] = " ioctl "; name[StatInt_sysinfo] = " sysinfo "; + name[StatInt_readdir] = " readdir "; + name[StatInt_readdir64] = " readdir64 "; + name[StatInt_readdir_r] = " readdir_r "; + name[StatInt_readdir64_r] = " readdir64_r "; name[StatAnnotation] = "Dynamic annotations "; name[StatAnnotateHappensBefore] = " HappensBefore "; diff --git a/lib/tsan/rtl/tsan_stat.h b/lib/tsan/rtl/tsan_stat.h index 3d6897050..6167f325f 100644 --- a/lib/tsan/rtl/tsan_stat.h +++ b/lib/tsan/rtl/tsan_stat.h @@ -326,6 +326,10 @@ enum StatType { StatInt_getpeername, StatInt_ioctl, StatInt_sysinfo, + StatInt_readdir, + StatInt_readdir64, + StatInt_readdir_r, + StatInt_readdir64_r, // Dynamic annotations. StatAnnotation, |