diff options
| author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-10-02 14:30:03 +0000 |
|---|---|---|
| committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-10-02 14:30:03 +0000 |
| commit | c907a60ffb64ebdc7e5754b0e15d5e68982e3ba8 (patch) | |
| tree | d23348bd26b62d4ce418c86f65c16a1d0f1705b0 | |
| parent | 34f4be1ce6338e65cc1e2c9a9ed1aac80ca4674a (diff) | |
| download | llvm-c907a60ffb64ebdc7e5754b0e15d5e68982e3ba8.zip llvm-c907a60ffb64ebdc7e5754b0e15d5e68982e3ba8.tar.gz llvm-c907a60ffb64ebdc7e5754b0e15d5e68982e3ba8.tar.bz2 | |
[sanitizer] Fix localtime and gmtime interceptors to clean tm->tm_zone.
llvm-svn: 191827
4 files changed, 52 insertions, 17 deletions
diff --git a/compiler-rt/lib/msan/tests/msan_test.cc b/compiler-rt/lib/msan/tests/msan_test.cc index 2f9c72e..c28f79b 100644 --- a/compiler-rt/lib/msan/tests/msan_test.cc +++ b/compiler-rt/lib/msan/tests/msan_test.cc @@ -1517,6 +1517,7 @@ TEST(MemorySanitizer, localtime) { EXPECT_NOT_POISONED(time->tm_hour); EXPECT_NOT_POISONED(time->tm_year); EXPECT_NOT_POISONED(time->tm_isdst); + EXPECT_NE(0, strlen(time->tm_zone)); } TEST(MemorySanitizer, localtime_r) { @@ -1528,6 +1529,7 @@ TEST(MemorySanitizer, localtime_r) { EXPECT_NOT_POISONED(time.tm_hour); EXPECT_NOT_POISONED(time.tm_year); EXPECT_NOT_POISONED(time.tm_isdst); + EXPECT_NE(0, strlen(time.tm_zone)); } TEST(MemorySanitizer, mmap) { diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 4b966d7..4be40b7 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -403,43 +403,50 @@ INTERCEPTOR(unsigned long, time, unsigned long *t) { #if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS -INTERCEPTOR(void *, localtime, unsigned long *timep) { +static void unpoison_tm(void *ctx, __sanitizer_tm *tm) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm)); + if (tm->tm_zone) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm->tm_zone, + REAL(strlen(tm->tm_zone)) + 1); +} + +INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep); - void *res = REAL(localtime)(timep); + __sanitizer_tm *res = REAL(localtime)(timep); if (res) { COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); + unpoison_tm(ctx, res); } return res; } -INTERCEPTOR(void *, localtime_r, unsigned long *timep, void *result) { +INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result); - void *res = REAL(localtime_r)(timep, result); + __sanitizer_tm *res = REAL(localtime_r)(timep, result); if (res) { COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); + unpoison_tm(ctx, res); } return res; } -INTERCEPTOR(void *, gmtime, unsigned long *timep) { +INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep); - void *res = REAL(gmtime)(timep); + __sanitizer_tm *res = REAL(gmtime)(timep); if (res) { COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); + unpoison_tm(ctx, res); } return res; } -INTERCEPTOR(void *, gmtime_r, unsigned long *timep, void *result) { +INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result); - void *res = REAL(gmtime_r)(timep, result); + __sanitizer_tm *res = REAL(gmtime_r)(timep, result); if (res) { COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); + unpoison_tm(ctx, res); } return res; } @@ -463,22 +470,22 @@ INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) { } return res; } -INTERCEPTOR(char *, asctime, void *tm) { +INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm); char *res = REAL(asctime)(tm); if (res) { - COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz); + COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); } return res; } -INTERCEPTOR(char *, asctime_r, void *tm, char *result) { +INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result); char *res = REAL(asctime_r)(tm, result); if (res) { - COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz); + COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); } return res; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc index bcf2c0a..9cc975a 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cc @@ -882,4 +882,17 @@ CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordv); CHECK_SIZE_AND_OFFSET(wordexp_t, we_offs); #endif +CHECK_TYPE_SIZE(tm); +CHECK_SIZE_AND_OFFSET(tm, tm_sec); +CHECK_SIZE_AND_OFFSET(tm, tm_min); +CHECK_SIZE_AND_OFFSET(tm, tm_hour); +CHECK_SIZE_AND_OFFSET(tm, tm_mday); +CHECK_SIZE_AND_OFFSET(tm, tm_mon); +CHECK_SIZE_AND_OFFSET(tm, tm_year); +CHECK_SIZE_AND_OFFSET(tm, tm_wday); +CHECK_SIZE_AND_OFFSET(tm, tm_yday); +CHECK_SIZE_AND_OFFSET(tm, tm_isdst); +CHECK_SIZE_AND_OFFSET(tm, tm_gmtoff); +CHECK_SIZE_AND_OFFSET(tm, tm_zone); + #endif // SANITIZER_LINUX || SANITIZER_MAC diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 2893ca7..f9573d4 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -22,7 +22,6 @@ namespace __sanitizer { extern unsigned struct_stat_sz; extern unsigned struct_stat64_sz; extern unsigned struct_rusage_sz; - extern unsigned struct_tm_sz; extern unsigned struct_passwd_sz; extern unsigned struct_group_sz; extern unsigned siginfo_t_sz; @@ -96,6 +95,20 @@ namespace __sanitizer { typedef unsigned __sanitizer_pthread_key_t; #endif + struct __sanitizer_tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + long int tm_gmtoff; + const char *tm_zone; + }; + #if SANITIZER_ANDROID || SANITIZER_MAC struct __sanitizer_msghdr { void *msg_name; |
