summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-10-18 09:41:43 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-10-18 09:41:43 +0000
commit4d7297daef90ad59446250617b72d184141436fc (patch)
treeb876f905289b154cf98121b3104df9a6a1db46ff
parenta2e70d92b67703effb631d7b4db8979fd74d5db5 (diff)
downloadcompiler-rt-4d7297daef90ad59446250617b72d184141436fc.tar.gz
compiler-rt-4d7297daef90ad59446250617b72d184141436fc.tar.bz2
compiler-rt-4d7297daef90ad59446250617b72d184141436fc.tar.xz
[sanitizer] Intercept getmntent, getmntent_r.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@192959 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/msan/tests/msan_test.cc29
-rw-r--r--lib/sanitizer_common/sanitizer_common_interceptors.inc48
-rw-r--r--lib/sanitizer_common/sanitizer_platform_interceptors.h2
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_posix.cc11
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_posix.h11
-rw-r--r--lib/tsan/rtl/tsan_stat.cc2
-rw-r--r--lib/tsan/rtl/tsan_stat.h2
7 files changed, 105 insertions, 0 deletions
diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc
index 0ed72765..73114aeb 100644
--- a/lib/msan/tests/msan_test.cc
+++ b/lib/msan/tests/msan_test.cc
@@ -50,6 +50,7 @@
#include <sys/socket.h>
#include <netdb.h>
#include <wordexp.h>
+#include <mntent.h>
#if defined(__i386__) || defined(__x86_64__)
# include <emmintrin.h>
@@ -1616,6 +1617,34 @@ TEST(MemorySanitizer, localtime_r) {
EXPECT_NE(0, strlen(time.tm_zone));
}
+TEST(MemorySanitizer, getmntent) {
+ FILE *fp = setmntent("/etc/fstab", "r");
+ struct mntent *mnt = getmntent(fp);
+ ASSERT_NE((void *)0, mnt);
+ ASSERT_NE(0, strlen(mnt->mnt_fsname));
+ ASSERT_NE(0, strlen(mnt->mnt_dir));
+ ASSERT_NE(0, strlen(mnt->mnt_type));
+ ASSERT_NE(0, strlen(mnt->mnt_opts));
+ EXPECT_NOT_POISONED(mnt->mnt_freq);
+ EXPECT_NOT_POISONED(mnt->mnt_passno);
+ fclose(fp);
+}
+
+TEST(MemorySanitizer, getmntent_r) {
+ FILE *fp = setmntent("/etc/fstab", "r");
+ struct mntent mntbuf;
+ char buf[1000];
+ struct mntent *mnt = getmntent_r(fp, &mntbuf, buf, sizeof(buf));
+ ASSERT_NE((void *)0, mnt);
+ ASSERT_NE(0, strlen(mnt->mnt_fsname));
+ ASSERT_NE(0, strlen(mnt->mnt_dir));
+ ASSERT_NE(0, strlen(mnt->mnt_type));
+ ASSERT_NE(0, strlen(mnt->mnt_opts));
+ EXPECT_NOT_POISONED(mnt->mnt_freq);
+ EXPECT_NOT_POISONED(mnt->mnt_passno);
+ fclose(fp);
+}
+
TEST(MemorySanitizer, mmap) {
const int size = 4096;
void *p1, *p2;
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc
index a88b4eb4..b34756d0 100644
--- a/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -2271,6 +2271,52 @@ INTERCEPTOR(int, pthread_cond_broadcast, void *c) {
#define INIT_PTHREAD_COND_BROADCAST
#endif
+#if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R
+static void write_mntent(void *ctx, __sanitizer_mntent *mnt) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt));
+ if (mnt->mnt_fsname)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname,
+ REAL(strlen)(mnt->mnt_fsname) + 1);
+ if (mnt->mnt_dir)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir,
+ REAL(strlen)(mnt->mnt_dir) + 1);
+ if (mnt->mnt_type)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type,
+ REAL(strlen)(mnt->mnt_type) + 1);
+ if (mnt->mnt_opts)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts,
+ REAL(strlen)(mnt->mnt_opts) + 1);
+}
+#endif
+
+#if SANITIZER_INTERCEPT_GETMNTENT
+INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp);
+ __sanitizer_mntent *res = REAL(getmntent)(fp);
+ if (res) write_mntent(ctx, res);
+ return res;
+}
+#define INIT_GETMNTENT INTERCEPT_FUNCTION(getmntent);
+#else
+#define INIT_GETMNTENT
+#endif
+
+#if SANITIZER_INTERCEPT_GETMNTENT_R
+INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp,
+ __sanitizer_mntent *mntbuf, char *buf, int buflen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen);
+ __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen);
+ if (res) write_mntent(ctx, res);
+ return res;
+}
+#define INIT_GETMNTENT_R INTERCEPT_FUNCTION(getmntent_r);
+#else
+#define INIT_GETMNTENT_R
+#endif
+
+
#define SANITIZER_COMMON_INTERCEPTORS_INIT \
INIT_STRCMP; \
INIT_STRNCMP; \
@@ -2355,4 +2401,6 @@ INTERCEPTOR(int, pthread_cond_broadcast, void *c) {
INIT_PTHREAD_COND_INIT; \
INIT_PTHREAD_COND_SIGNAL; \
INIT_PTHREAD_COND_BROADCAST; \
+ INIT_GETMNTENT; \
+ INIT_GETMNTENT_R; \
/**/
diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h
index 1c15b50b..e2ae57b4 100644
--- a/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -126,6 +126,8 @@
# define SANITIZER_INTERCEPT_SIGPENDING SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_SIGPROCMASK SI_NOT_WINDOWS
# define SANITIZER_INTERCEPT_BACKTRACE SI_LINUX_NOT_ANDROID
+# define SANITIZER_INTERCEPT_GETMNTENT SI_LINUX
+# define SANITIZER_INTERCEPT_GETMNTENT_R SI_LINUX_NOT_ANDROID
# define SANITIZER_INTERCEPT__EXIT SI_LINUX
diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
index 67970471..cf1c7cd3 100644
--- a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
+++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
@@ -44,6 +44,7 @@
#include <wchar.h>
#if SANITIZER_LINUX
+#include <mntent.h>
#include <utime.h>
#include <sys/mount.h>
#include <sys/ptrace.h>
@@ -896,4 +897,14 @@ CHECK_SIZE_AND_OFFSET(tm, tm_isdst);
CHECK_SIZE_AND_OFFSET(tm, tm_gmtoff);
CHECK_SIZE_AND_OFFSET(tm, tm_zone);
+#if SANITIZER_LINUX
+CHECK_TYPE_SIZE(mntent);
+CHECK_SIZE_AND_OFFSET(mntent, mnt_fsname);
+CHECK_SIZE_AND_OFFSET(mntent, mnt_dir);
+CHECK_SIZE_AND_OFFSET(mntent, mnt_type);
+CHECK_SIZE_AND_OFFSET(mntent, mnt_opts);
+CHECK_SIZE_AND_OFFSET(mntent, mnt_freq);
+CHECK_SIZE_AND_OFFSET(mntent, mnt_passno);
+#endif
+
#endif // SANITIZER_LINUX || SANITIZER_MAC
diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/lib/sanitizer_common/sanitizer_platform_limits_posix.h
index 563a490b..4c51380e 100644
--- a/lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -111,6 +111,17 @@ namespace __sanitizer {
const char *tm_zone;
};
+#if SANITIZER_LINUX
+ struct __sanitizer_mntent {
+ char *mnt_fsname;
+ char *mnt_dir;
+ char *mnt_type;
+ char *mnt_opts;
+ int mnt_freq;
+ int mnt_passno;
+ };
+#endif
+
#if SANITIZER_ANDROID || SANITIZER_MAC
struct __sanitizer_msghdr {
void *msg_name;
diff --git a/lib/tsan/rtl/tsan_stat.cc b/lib/tsan/rtl/tsan_stat.cc
index 30b4a952..922a5f44 100644
--- a/lib/tsan/rtl/tsan_stat.cc
+++ b/lib/tsan/rtl/tsan_stat.cc
@@ -374,6 +374,8 @@ void StatOutput(u64 *stat) {
name[StatInt_backtrace_symbols] = " backtrace_symbols ";
name[StatInt_dlopen] = " dlopen ";
name[StatInt_dlclose] = " dlclose ";
+ name[StatInt_getmntent] = " getmntent ";
+ name[StatInt_getmntent_r] = " getmntent_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 9129b221..c98ad6bc 100644
--- a/lib/tsan/rtl/tsan_stat.h
+++ b/lib/tsan/rtl/tsan_stat.h
@@ -369,6 +369,8 @@ enum StatType {
StatInt_backtrace_symbols,
StatInt_dlopen,
StatInt_dlclose,
+ StatInt_getmntent,
+ StatInt_getmntent_r,
// Dynamic annotations.
StatAnnotation,