[llvm-commits] [compiler-rt] r147315 - in /compiler-rt/trunk/lib/asan: asan_interceptors.cc asan_interceptors.h asan_stack.cc tests/asan_test.cc
Kostya Serebryany
kcc at google.com
Wed Dec 28 10:56:43 PST 2011
Author: kcc
Date: Wed Dec 28 12:56:42 2011
New Revision: 147315
URL: http://llvm.org/viewvc/llvm-project?rev=147315&view=rev
Log:
[asan] interceptor for memcmp. Patch by samsonov at google.com
Modified:
compiler-rt/trunk/lib/asan/asan_interceptors.cc
compiler-rt/trunk/lib/asan/asan_interceptors.h
compiler-rt/trunk/lib/asan/asan_stack.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=147315&r1=147314&r2=147315&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Wed Dec 28 12:56:42 2011
@@ -28,6 +28,7 @@
namespace __asan {
index_f real_index;
+memcmp_f real_memcmp;
memcpy_f real_memcpy;
memmove_f real_memmove;
memset_f real_memset;
@@ -124,6 +125,7 @@
#else
OVERRIDE_FUNCTION(index, WRAP(strchr));
#endif
+ INTERCEPT_FUNCTION(memcmp);
INTERCEPT_FUNCTION(memcpy);
INTERCEPT_FUNCTION(memmove);
INTERCEPT_FUNCTION(memset);
@@ -149,6 +151,32 @@
// ---------------------- Wrappers ---------------- {{{1
using namespace __asan; // NOLINT
+static inline int CharCmp(unsigned char c1, unsigned char c2) {
+ return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
+}
+
+static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
+ int c1_low = tolower(c1);
+ int c2_low = tolower(c2);
+ return c1_low - c2_low;
+}
+
+int WRAP(memcmp)(const void *a1, const void *a2, size_t size) {
+ ENSURE_ASAN_INITED();
+ unsigned char c1 = 0, c2 = 0;
+ const unsigned char *s1 = (const unsigned char*)a1;
+ const unsigned char *s2 = (const unsigned char*)a2;
+ size_t i;
+ for (i = 0; i < size; i++) {
+ c1 = s1[i];
+ c2 = s2[i];
+ if (c1 != c2) break;
+ }
+ ASAN_READ_RANGE(s1, Min(i + 1, size));
+ ASAN_READ_RANGE(s2, Min(i + 1, size));
+ return CharCmp(c1, c2);
+}
+
void *WRAP(memcpy)(void *to, const void *from, size_t size) {
// memcpy is called during __asan_init() from the internals
// of printf(...).
@@ -204,16 +232,6 @@
return result;
}
-static inline int CharCmp(unsigned char c1, unsigned char c2) {
- return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
-}
-
-static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
- int c1_low = tolower(c1);
- int c2_low = tolower(c2);
- return c1_low - c2_low;
-}
-
int WRAP(strcasecmp)(const char *s1, const char *s2) {
ENSURE_ASAN_INITED();
unsigned char c1, c2;
Modified: compiler-rt/trunk/lib/asan/asan_interceptors.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.h?rev=147315&r1=147314&r2=147315&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.h (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.h Wed Dec 28 12:56:42 2011
@@ -67,6 +67,7 @@
#endif
#ifdef __APPLE__
+int WRAP(memcmp)(const void *a1, const void *a2, size_t size);
void *WRAP(memcpy)(void *to, const void *from, size_t size);
void *WRAP(memmove)(void *to, const void *from, size_t size);
void *WRAP(memset)(void *block, int c, size_t size);
@@ -84,6 +85,7 @@
namespace __asan {
typedef void* (*index_f)(const char *string, int c);
+typedef int (*memcmp_f)(const void *a1, const void *a2, size_t size);
typedef void* (*memcpy_f)(void *to, const void *from, size_t size);
typedef void* (*memmove_f)(void *to, const void *from, size_t size);
typedef void* (*memset_f)(void *block, int c, size_t size);
@@ -100,6 +102,7 @@
// __asan::real_X() holds pointer to library implementation of X().
extern index_f real_index;
+extern memcmp_f real_memcmp;
extern memcpy_f real_memcpy;
extern memmove_f real_memmove;
extern memset_f real_memset;
Modified: compiler-rt/trunk/lib/asan/asan_stack.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_stack.cc?rev=147315&r1=147314&r2=147315&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_stack.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_stack.cc Wed Dec 28 12:56:42 2011
@@ -230,8 +230,8 @@
// |res| may be greater than check_stack.size, because
// UncompressStack(CompressStack(stack)) eliminates the 0x0 frames.
CHECK(res >= check_stack.size);
- CHECK(0 == memcmp(check_stack.trace, stack->trace,
- check_stack.size * sizeof(uintptr_t)));
+ CHECK(0 == real_memcmp(check_stack.trace, stack->trace,
+ check_stack.size * sizeof(uintptr_t)));
#endif
return res;
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=147315&r1=147314&r2=147315&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/tests/asan_test.cc (original)
+++ compiler-rt/trunk/lib/asan/tests/asan_test.cc Wed Dec 28 12:56:42 2011
@@ -1220,6 +1220,14 @@
EXPECT_LT(0, strncasecmp("xyz", "xyy", 10));
EXPECT_LT(0, strncasecmp("Baa", "aaa", 1));
EXPECT_LT(0, strncasecmp("zyx", "", 2));
+
+ // memcmp
+ EXPECT_EQ(0, memcmp("a", "b", 0));
+ EXPECT_EQ(0, memcmp("ab\0c", "ab\0c", 4));
+ EXPECT_GT(0, memcmp("\0ab", "\0ac", 3));
+ EXPECT_GT(0, memcmp("abb\0", "abba", 4));
+ EXPECT_LT(0, memcmp("ab\0cd", "ab\0c\0", 5));
+ EXPECT_LT(0, memcmp("zza", "zyx", 3));
}
typedef int(*PointerToStrCmp)(const char*, const char*);
@@ -1292,6 +1300,30 @@
RunStrNCmpTest(&strncasecmp);
}
+TEST(AddressSanitizer, MemCmpOOBTest) {
+ size_t size = Ident(100);
+ char *s1 = MallocAndMemsetString(size);
+ char *s2 = MallocAndMemsetString(size);
+ // Normal memcmp calls.
+ Ident(memcmp(s1, s2, size));
+ Ident(memcmp(s1 + size - 1, s2 + size - 1, 1));
+ Ident(memcmp(s1 - 1, s2 - 1, 0));
+ // One of arguments points to not allocated memory.
+ EXPECT_DEATH(Ident(memcmp)(s1 - 1, s2, 1), LeftOOBErrorMessage(1));
+ EXPECT_DEATH(Ident(memcmp)(s1, s2 - 1, 1), LeftOOBErrorMessage(1));
+ EXPECT_DEATH(Ident(memcmp)(s1 + size, s2, 1), RightOOBErrorMessage(0));
+ EXPECT_DEATH(Ident(memcmp)(s1, s2 + size, 1), RightOOBErrorMessage(0));
+ // Hit unallocated memory and die.
+ EXPECT_DEATH(Ident(memcmp)(s1 + 1, s2 + 1, size), RightOOBErrorMessage(0));
+ EXPECT_DEATH(Ident(memcmp)(s1 + size - 1, s2, 2), RightOOBErrorMessage(0));
+ // Zero bytes are not terminators and don't prevent from OOB.
+ s1[size - 1] = '\0';
+ s2[size - 1] = '\0';
+ EXPECT_DEATH(Ident(memcmp)(s1, s2, size + 1), RightOOBErrorMessage(0));
+ free(s1);
+ free(s2);
+}
+
static const char *kOverlapErrorMessage = "strcpy-param-overlap";
TEST(AddressSanitizer, StrArgsOverlapTest) {
More information about the llvm-commits
mailing list