summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-11-02 01:01:35 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2013-11-02 01:01:35 +0000
commite4f9f8a1296768a7a6b6646a3b241a379f4a5e15 (patch)
tree052bc5234515fe9111d028ae73b70e0f7fad4263
parent5492ff9a1730b6b7a6d7ab70a14e60be1f44b0c9 (diff)
downloadcompiler-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.cc2
-rw-r--r--lib/msan/tests/msan_test.cc9
-rw-r--r--lib/sanitizer_common/sanitizer_common_interceptors.inc26
-rw-r--r--lib/sanitizer_common/sanitizer_platform_interceptors.h1
-rw-r--r--lib/tsan/rtl/tsan_stat.cc1
-rw-r--r--lib/tsan/rtl/tsan_stat.h1
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,