[asan] fix the output for range accesses (memset, etc); improve the tests; more strict checking in memcmp

llvm-svn: 176078
This commit is contained in:
Kostya Serebryany 2013-02-26 07:25:18 +00:00
parent c8ac15a66b
commit 8caf654731
3 changed files with 18 additions and 14 deletions

View File

@ -44,10 +44,11 @@ static inline bool QuickCheckForUnpoisonedRegion(uptr beg, uptr size) {
#define ACCESS_MEMORY_RANGE(offset, size, isWrite) do { \
uptr __offset = (uptr)(offset); \
uptr __size = (uptr)(size); \
uptr __bad = 0; \
if (!QuickCheckForUnpoisonedRegion(__offset, __size) && \
__asan_region_is_poisoned(__offset, __size)) { \
(__bad = __asan_region_is_poisoned(__offset, __size))) { \
GET_CURRENT_PC_BP_SP; \
__asan_report_error(pc, bp, sp, __offset, isWrite, __size); \
__asan_report_error(pc, bp, sp, __bad, isWrite, __size); \
} \
} while (0)
@ -258,18 +259,13 @@ static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
if (!asan_inited) return internal_memcmp(a1, a2, 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;
uptr i;
for (i = 0; i < size; i++) {
c1 = s1[i];
c2 = s2[i];
if (c1 != c2) break;
if (flags()->replace_intrin) {
// We check the entire regions even if the first bytes of the buffers
// are different.
ASAN_READ_RANGE(a1, size);
ASAN_READ_RANGE(a2, size);
}
ASAN_READ_RANGE(s1, Min(i + 1, size));
ASAN_READ_RANGE(s2, Min(i + 1, size));
return CharCmp(c1, c2);
return REAL(memcmp(a1, a2, size));
}
INTERCEPTOR(void*, memcpy, void *to, const void *from, uptr size) {

View File

@ -225,6 +225,13 @@ TEST(AddressSanitizer, MemCmpOOBTest) {
s1[size - 1] = '\0';
s2[size - 1] = '\0';
EXPECT_DEATH(Ident(memcmp)(s1, s2, size + 1), RightOOBReadMessage(0));
// Even if the buffers differ in the first byte, we still assume that
// memcmp may access the whole buffer and thus reporting the overflow here:
s1[0] = 1;
s2[0] = 123;
EXPECT_DEATH(Ident(memcmp)(s1, s2, size + 1), RightOOBReadMessage(0));
free(s1);
free(s2);
}

View File

@ -716,7 +716,8 @@ TEST(AddressSanitizer, Store128Test) {
string RightOOBErrorMessage(int oob_distance, bool is_write) {
assert(oob_distance >= 0);
char expected_str[100];
sprintf(expected_str, ASAN_PCRE_DOTALL "%s.*located %d bytes to the right",
sprintf(expected_str, ASAN_PCRE_DOTALL
"buffer-overflow.*%s.*located %d bytes to the right",
is_write ? "WRITE" : "READ", oob_distance);
return string(expected_str);
}