diff options
-rw-r--r-- | lib/msan/tests/msan_test.cc | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_common_interceptors.inc | 39 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_limits_posix.cc | 13 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_limits_posix.h | 15 |
4 files changed, 52 insertions, 17 deletions
diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc index 2f9c72e19..c28f79b44 100644 --- a/lib/msan/tests/msan_test.cc +++ b/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/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc index 4b966d756..4be40b747 100644 --- a/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/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/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc index bcf2c0a50..9cc975a0a 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc +++ b/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/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 2893ca7b5..f9573d4e4 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/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; |