diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-11-02 01:01:35 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-11-02 01:01:35 +0000 |
commit | e4f9f8a1296768a7a6b6646a3b241a379f4a5e15 (patch) | |
tree | 052bc5234515fe9111d028ae73b70e0f7fad4263 | |
parent | 5492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9 (diff) | |
download | compiler-rt-e4f9f8a1296768a7a6b6646a3b241a379f4a5e15.tar.gz compiler-rt-e4f9f8a1296768a7a6b6646a3b241a379f4a5e15.tar.bz2 compiler-rt-e4f9f8a1296768a7a6b6646a3b241a379f4a5e15.tar.xz |
[sanitizer] Intercept strptime.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@193903 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/msan/msan_interceptors.cc | 2 | ||||
-rw-r--r-- | lib/msan/tests/msan_test.cc | 9 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_common_interceptors.inc | 26 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_interceptors.h | 1 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_stat.cc | 1 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_stat.h | 1 |
6 files changed, 37 insertions, 3 deletions
diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc index de22f850..0e2db9cb 100644 --- a/lib/msan/msan_interceptors.cc +++ b/lib/msan/msan_interceptors.cc @@ -495,7 +495,7 @@ INTERCEPTOR(int, swprintf, void *str, uptr size, void *format, ...) { // SIZE_T strftime(char *s, SIZE_T max, const char *format,const struct tm *tm); INTERCEPTOR(SIZE_T, strftime, char *s, SIZE_T max, const char *format, - void *tm) { + __sanitizer_tm *tm) { ENSURE_MSAN_INITED(); SIZE_T res = REAL(strftime)(s, max, format, tm); if (res) __msan_unpoison(s, res + 1); diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc index c387567d..406808af 100644 --- a/lib/msan/tests/msan_test.cc +++ b/lib/msan/tests/msan_test.cc @@ -1860,6 +1860,15 @@ TEST(MemorySanitizer, time) { EXPECT_NOT_POISONED(t); } +TEST(MemorySanitizer, strptime) { + struct tm time; + char *p = strptime("11/1/2013-05:39", "%m/%d/%Y-%H:%M", &time); + assert(p != 0); + EXPECT_NOT_POISONED(time.tm_sec); + EXPECT_NOT_POISONED(time.tm_hour); + EXPECT_NOT_POISONED(time.tm_year); +} + TEST(MemorySanitizer, localtime) { time_t t = 123; struct tm *time = localtime(&t); diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc index 3e716a7c..a31a3f19 100644 --- a/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -435,7 +435,6 @@ INTERCEPTOR(unsigned long, time, unsigned long *t) { #define INIT_TIME #endif // SANITIZER_INTERCEPT_TIME - #if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS static void unpoison_tm(void *ctx, __sanitizer_tm *tm) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm)); @@ -446,7 +445,6 @@ static void unpoison_tm(void *ctx, __sanitizer_tm *tm) { REAL(strlen(tm->tm_zone)) + 1); } } - INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep); @@ -540,6 +538,29 @@ INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) { #define INIT_LOCALTIME_AND_FRIENDS #endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS +#if SANITIZER_INTERCEPT_STRPTIME +INTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm); + if (format) + COMMON_INTERCEPTOR_READ_RANGE(ctx, format, REAL(strlen)(format) + 1); + char *res = REAL(strptime)(s, format, tm); + if (res) { + COMMON_INTERCEPTOR_READ_RANGE(ctx, s, res - s); + // Do not call unpoison_tm here, because strptime does not, in fact, + // initialize the entire struct tm. For example, tm_zone pointer is left + // uninitialized. + if (tm) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm)); + } + return res; +} +#define INIT_STRPTIME INTERCEPT_FUNCTION(strptime); +#else +#define INIT_STRPTIME +#endif + + #if SANITIZER_INTERCEPT_SCANF #include "sanitizer_common_interceptors_scanf.inc" @@ -2861,6 +2882,7 @@ INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim, INIT_PWRITEV64; \ INIT_PRCTL; \ INIT_LOCALTIME_AND_FRIENDS; \ + INIT_STRPTIME; \ INIT_SCANF; \ INIT_ISOC99_SCANF; \ INIT_FREXP; \ diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h index 1d6fe010..78d1f5ad 100644 --- a/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -69,6 +69,7 @@ # define SANITIZER_INTERCEPT_PRCTL SI_LINUX # define SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS SI_NOT_WINDOWS +# define SANITIZER_INTERCEPT_STRPTIME SI_NOT_WINDOWS # define SANITIZER_INTERCEPT_SCANF SI_NOT_WINDOWS # define SANITIZER_INTERCEPT_ISOC99_SCANF SI_LINUX diff --git a/lib/tsan/rtl/tsan_stat.cc b/lib/tsan/rtl/tsan_stat.cc index 72d173de..f9dbf121 100644 --- a/lib/tsan/rtl/tsan_stat.cc +++ b/lib/tsan/rtl/tsan_stat.cc @@ -292,6 +292,7 @@ void StatOutput(u64 *stat) { name[StatInt_ctime_r] = " ctime_r "; name[StatInt_asctime] = " asctime "; name[StatInt_asctime_r] = " asctime_r "; + name[StatInt_strptime] = " strptime "; name[StatInt_frexp] = " frexp "; name[StatInt_frexpf] = " frexpf "; name[StatInt_frexpl] = " frexpl "; diff --git a/lib/tsan/rtl/tsan_stat.h b/lib/tsan/rtl/tsan_stat.h index d6ff93c5..a44edfcd 100644 --- a/lib/tsan/rtl/tsan_stat.h +++ b/lib/tsan/rtl/tsan_stat.h @@ -287,6 +287,7 @@ enum StatType { StatInt_ctime_r, StatInt_asctime, StatInt_asctime_r, + StatInt_strptime, StatInt_frexp, StatInt_frexpf, StatInt_frexpl, |