summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-06-26 15:00:53 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-06-26 15:00:53 +0000
commitb5cf98f76fd62236f2945bff17b3cdb4e8a5c2f4 (patch)
tree6639f74e4125b99260e63742df09df8c358cc64f /lib
parent7a0bba457ee05ced3adf37a0c0790d0ed23a5446 (diff)
downloadcompiler-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.cc16
-rw-r--r--lib/msan/tests/msan_test.cc11
-rw-r--r--lib/sanitizer_common/sanitizer_common_interceptors.inc64
-rw-r--r--lib/sanitizer_common/sanitizer_platform_interceptors.h2
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_posix.cc2
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_posix.h2
-rw-r--r--lib/tsan/rtl/tsan_stat.cc4
-rw-r--r--lib/tsan/rtl/tsan_stat.h4
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,