[sanitizer] Intercept strptime.

llvm-svn: 193903
This commit is contained in:
Evgeniy Stepanov 2013-11-02 01:01:35 +00:00
parent 5d80bfa746
commit a6b5eec757
6 changed files with 37 additions and 3 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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; \

View File

@ -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

View File

@ -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 ";

View File

@ -287,6 +287,7 @@ enum StatType {
StatInt_ctime_r,
StatInt_asctime,
StatInt_asctime_r,
StatInt_strptime,
StatInt_frexp,
StatInt_frexpf,
StatInt_frexpl,