summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/msan/tests/msan_test.cc2
-rw-r--r--lib/sanitizer_common/sanitizer_common_interceptors.inc39
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_posix.cc13
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_posix.h15
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;