[llvm-commits] [compiler-rt] r153444 - in /compiler-rt/trunk/lib/asan: asan_interceptors.cc tests/asan_test.cc
Alexey Samsonov
samsonov at google.com
Mon Mar 26 09:42:23 PDT 2012
Author: samsonov
Date: Mon Mar 26 11:42:22 2012
New Revision: 153444
URL: http://llvm.org/viewvc/llvm-project?rev=153444&view=rev
Log:
[ASan] add interceptor for strtol
Modified:
compiler-rt/trunk/lib/asan/asan_interceptors.cc
compiler-rt/trunk/lib/asan/tests/asan_test.cc
Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=153444&r1=153443&r2=153444&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Mon Mar 26 11:42:22 2012
@@ -89,6 +89,7 @@
# endif
// stdlib.h
+long strtol(const char *nptr, char **endptr, int base); // NOLINT
# if ASAN_INTERCEPT_STRTOLL
long long strtoll(const char *nptr, char **endptr, int base); // NOLINT
# endif
@@ -659,15 +660,24 @@
}
#endif // ASAN_INTERCEPT_STRNLEN
-# if ASAN_INTERCEPT_STRTOLL
-// Returns pointer to first character of "nptr" after skipping
-// leading blanks and optional +/- sign.
-static char *SkipBlanksAndSign(const char *nptr) {
- while (IsSpace(*nptr)) nptr++;
- if (*nptr == '+' || *nptr == '-') nptr++;
- return (char*)nptr;
+static inline bool IsValidStrtolBase(int base) {
+ return (base == 0) || (2 <= base && base <= 36);
+}
+
+static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) {
+ CHECK(endptr != NULL);
+ if (nptr == *endptr) {
+ // No digits were found at strtol call, we need to find out the last
+ // symbol accessed by strtoll on our own.
+ // We get this symbol by skipping leading blanks and optional +/- sign.
+ while (IsSpace(*nptr)) nptr++;
+ if (*nptr == '+' || *nptr == '-') nptr++;
+ *endptr = (char*)nptr;
+ }
+ CHECK(*endptr >= nptr);
}
+# if ASAN_INTERCEPT_STRTOLL
INTERCEPTOR(long long, strtoll, const char *nptr, // NOLINT
char **endptr, int base) {
ENSURE_ASAN_INITED();
@@ -682,19 +692,32 @@
// If base has unsupported value, strtoll can exit with EINVAL
// without reading any characters. So do additional checks only
// if base is valid.
- if (base == 0 || (2 <= base && base <= 36)) {
- if (real_endptr == nptr) {
- // No digits were found, find out the last symbol read by strtoll
- // on our own.
- real_endptr = SkipBlanksAndSign(nptr);
- }
- CHECK(real_endptr >= nptr);
+ 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
+ char **endptr, int base) {
+ ENSURE_ASAN_INITED();
+ if (!FLAG_replace_str) {
+ return REAL(strtol)(nptr, endptr, base);
+ }
+ char *real_endptr;
+ long result = REAL(strtol)(nptr, &real_endptr, base); // NOLINT
+ if (endptr != NULL) {
+ *endptr = real_endptr;
+ }
+ if (IsValidStrtolBase(base)) {
+ FixRealStrtolEndptr(nptr, &real_endptr);
+ ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
+ }
+ return result;
+}
+
#if defined(_WIN32)
INTERCEPTOR_WINAPI(DWORD, CreateThread,
void* security, size_t stack_size,
@@ -754,6 +777,7 @@
CHECK(INTERCEPT_FUNCTION(strnlen));
#endif
+ CHECK(INTERCEPT_FUNCTION(strtol));
#if ASAN_INTERCEPT_STRTOLL
CHECK(INTERCEPT_FUNCTION(strtoll));
#endif
Modified: compiler-rt/trunk/lib/asan/tests/asan_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/tests/asan_test.cc?rev=153444&r1=153443&r2=153444&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/tests/asan_test.cc (original)
+++ compiler-rt/trunk/lib/asan/tests/asan_test.cc Mon Mar 26 11:42:22 2012
@@ -1349,46 +1349,61 @@
free(str);
}
-TEST(AddressSanitizer, StrtollOOBTest) {
+void CallStrtol(const char *nptr, char **endptr, int base) {
+ Ident(strtol(nptr, endptr, base));
+}
+void CallStrtoll(const char *nptr, char **endptr, int base) {
+ Ident(strtoll(nptr, endptr, base));
+}
+typedef void(*PointerToCallStrtol)(const char*, char**, int);
+
+void RunStrtolOOBTest(PointerToCallStrtol Strtol) {
char *array = MallocAndMemsetString(3);
char *endptr = NULL;
array[0] = '1';
array[1] = '2';
array[2] = '3';
// Invalid pointer to the string.
- EXPECT_DEATH(strtoll(array + 3, NULL, 0), RightOOBErrorMessage(0));
- EXPECT_DEATH(strtoll(array - 1, NULL, 0), LeftOOBErrorMessage(1));
+ EXPECT_DEATH(Strtol(array + 3, NULL, 0), RightOOBErrorMessage(0));
+ EXPECT_DEATH(Strtol(array - 1, NULL, 0), LeftOOBErrorMessage(1));
// Buffer overflow if there is no terminating null (depends on base).
- Ident(strtoll(array, &endptr, 3));
+ Strtol(array, &endptr, 3);
EXPECT_EQ(array + 2, endptr);
- EXPECT_DEATH(strtoll(array, NULL, 0), RightOOBErrorMessage(0));
+ EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBErrorMessage(0));
array[2] = 'z';
- Ident(strtoll(array, &endptr, 35));
+ Strtol(array, &endptr, 35);
EXPECT_EQ(array + 2, endptr);
- EXPECT_DEATH(strtoll(array, NULL, 36), RightOOBErrorMessage(0));
+ EXPECT_DEATH(Strtol(array, NULL, 36), RightOOBErrorMessage(0));
// Add terminating zero to get rid of overflow.
array[2] = '\0';
- Ident(strtoll(array, NULL, 36));
+ Strtol(array, NULL, 36);
// Don't check for overflow if base is invalid.
- Ident(strtoll(array - 1, NULL, -1));
- Ident(strtoll(array + 3, NULL, 1));
+ Strtol(array - 1, NULL, -1);
+ Strtol(array + 3, NULL, 1);
// Sometimes we need to detect overflow if no digits are found.
array[0] = array[1] = array[2] = ' ';
- EXPECT_DEATH(strtoll(array, NULL, 0), RightOOBErrorMessage(0));
+ EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBErrorMessage(0));
array[2] = '+';
- EXPECT_DEATH(strtoll(array, NULL, 0), RightOOBErrorMessage(0));
+ EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBErrorMessage(0));
array[2] = '-';
- EXPECT_DEATH(strtoll(array, NULL, 0), RightOOBErrorMessage(0));
+ EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBErrorMessage(0));
array[1] = '+';
- Ident(strtoll(array, NULL, 0));
+ Strtol(array, NULL, 0);
array[1] = array[2] = 'z';
- Ident(strtoll(array, &endptr, 0));
+ Strtol(array, &endptr, 0);
EXPECT_EQ(array, endptr);
- Ident(strtoll(array + 2, NULL, 0));
+ Strtol(array + 2, NULL, 0);
EXPECT_EQ(array, endptr);
delete array;
}
+TEST(AddressSanitizer, StrtollOOBTest) {
+ RunStrtolOOBTest(&CallStrtoll);
+}
+TEST(AddressSanitizer, StrtolOOBTest) {
+ RunStrtolOOBTest(&CallStrtol);
+}
+
// At the moment we instrument memcpy/memove/memset calls at compile time so we
// can't handle OOB error if these functions are called by pointer, see disabled
// MemIntrinsicCallByPointerTest below
More information about the llvm-commits
mailing list