diff options
Diffstat (limited to 'compiler-rt/lib/asan/asan_interceptors.cc')
-rw-r--r-- | compiler-rt/lib/asan/asan_interceptors.cc | 76 |
1 files changed, 61 insertions, 15 deletions
diff --git a/compiler-rt/lib/asan/asan_interceptors.cc b/compiler-rt/lib/asan/asan_interceptors.cc index 8228121374a..a11601994e4 100644 --- a/compiler-rt/lib/asan/asan_interceptors.cc +++ b/compiler-rt/lib/asan/asan_interceptors.cc @@ -27,9 +27,9 @@ // Use macro to describe if specific function should be // intercepted on a given platform. #if !defined(_WIN32) -# define ASAN_INTERCEPT_STRTOLL 1 +# define ASAN_INTERCEPT_ATOLL_AND_STRTOLL 1 #else -# define ASAN_INTERCEPT_STRTOLL 0 +# define ASAN_INTERCEPT_ATOLL_AND_STRTOLL 0 #endif #if !defined(__APPLE__) @@ -89,8 +89,11 @@ size_t strnlen(const char *s, size_t maxlen); # endif // stdlib.h +int atoi(const char *nptr); +long atol(const char *nptr); // NOLINT long strtol(const char *nptr, char **endptr, int base); // NOLINT -# if ASAN_INTERCEPT_STRTOLL +# if ASAN_INTERCEPT_ATOLL_AND_STRTOLL +long long atoll(const char *nptr); // NOLINT long long strtoll(const char *nptr, char **endptr, int base); // NOLINT # endif @@ -677,40 +680,67 @@ static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) { CHECK(*endptr >= nptr); } -# if ASAN_INTERCEPT_STRTOLL -INTERCEPTOR(long long, strtoll, const char *nptr, // NOLINT +INTERCEPTOR(long, strtol, const char *nptr, // NOLINT char **endptr, int base) { ENSURE_ASAN_INITED(); if (!FLAG_replace_str) { - return REAL(strtoll)(nptr, endptr, base); + return REAL(strtol)(nptr, endptr, base); } char *real_endptr; - long long result = REAL(strtoll)(nptr, &real_endptr, base); // NOLINT + long result = REAL(strtol)(nptr, &real_endptr, base); // NOLINT if (endptr != NULL) { *endptr = real_endptr; } - // If base has unsupported value, strtoll can exit with EINVAL - // without reading any characters. So do additional checks only - // if base is valid. if (IsValidStrtolBase(base)) { FixRealStrtolEndptr(nptr, &real_endptr); ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); } return result; } -#endif // ASAN_INTERCEPT_STRTOLL -INTERCEPTOR(long, strtol, const char *nptr, // NOLINT +INTERCEPTOR(int, atoi, const char *nptr) { + ENSURE_ASAN_INITED(); + if (!FLAG_replace_str) { + return REAL(atoi)(nptr); + } + char *real_endptr; + // "man atoi" tells that behavior of atoi(nptr) is the same as + // strtol(nptr, NULL, 10), i.e. it sets errno to ERANGE if the + // parsed integer can't be stored in *long* type (even if it's + // different from int). So, we just imitate this behavior. + int result = REAL(strtol)(nptr, &real_endptr, 10); + FixRealStrtolEndptr(nptr, &real_endptr); + ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); + return result; +} + +INTERCEPTOR(long, atol, const char *nptr) { // NOLINT + ENSURE_ASAN_INITED(); + if (!FLAG_replace_str) { + return REAL(atol)(nptr); + } + char *real_endptr; + long result = REAL(strtol)(nptr, &real_endptr, 10); // NOLINT + FixRealStrtolEndptr(nptr, &real_endptr); + ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); + return result; +} + +#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL +INTERCEPTOR(long long, strtoll, const char *nptr, // NOLINT char **endptr, int base) { ENSURE_ASAN_INITED(); if (!FLAG_replace_str) { - return REAL(strtol)(nptr, endptr, base); + return REAL(strtoll)(nptr, endptr, base); } char *real_endptr; - long result = REAL(strtol)(nptr, &real_endptr, base); // NOLINT + long long result = REAL(strtoll)(nptr, &real_endptr, base); // NOLINT if (endptr != NULL) { *endptr = real_endptr; } + // If base has unsupported value, strtoll can exit with EINVAL + // without reading any characters. So do additional checks only + // if base is valid. if (IsValidStrtolBase(base)) { FixRealStrtolEndptr(nptr, &real_endptr); ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); @@ -718,6 +748,19 @@ INTERCEPTOR(long, strtol, const char *nptr, // NOLINT return result; } +INTERCEPTOR(long long, atoll, const char *nptr) { // NOLINT + ENSURE_ASAN_INITED(); + if (!FLAG_replace_str) { + return REAL(atoll)(nptr); + } + char *real_endptr; + long long result = REAL(strtoll)(nptr, &real_endptr, 10); // NOLINT + FixRealStrtolEndptr(nptr, &real_endptr); + ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); + return result; +} +#endif // ASAN_INTERCEPT_ATOLL_AND_STRTOLL + #if defined(_WIN32) INTERCEPTOR_WINAPI(DWORD, CreateThread, void* security, size_t stack_size, @@ -777,8 +820,11 @@ void InitializeAsanInterceptors() { CHECK(INTERCEPT_FUNCTION(strnlen)); #endif + CHECK(INTERCEPT_FUNCTION(atoi)); + CHECK(INTERCEPT_FUNCTION(atol)); CHECK(INTERCEPT_FUNCTION(strtol)); -#if ASAN_INTERCEPT_STRTOLL +#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL + CHECK(INTERCEPT_FUNCTION(atoll)); CHECK(INTERCEPT_FUNCTION(strtoll)); #endif |