From 4d7297daef90ad59446250617b72d184141436fc Mon Sep 17 00:00:00 2001 From: Evgeniy Stepanov Date: Fri, 18 Oct 2013 09:41:43 +0000 Subject: [sanitizer] Intercept getmntent, getmntent_r. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@192959 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/msan/tests/msan_test.cc | 29 +++++++++++++ .../sanitizer_common_interceptors.inc | 48 ++++++++++++++++++++++ .../sanitizer_platform_interceptors.h | 2 + .../sanitizer_platform_limits_posix.cc | 11 +++++ .../sanitizer_platform_limits_posix.h | 11 +++++ lib/tsan/rtl/tsan_stat.cc | 2 + lib/tsan/rtl/tsan_stat.h | 2 + 7 files changed, 105 insertions(+) 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 #include #include +#include #if defined(__i386__) || defined(__x86_64__) # include @@ -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 #if SANITIZER_LINUX +#include #include #include #include @@ -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, -- cgit v1.2.3