Skip to content

Commit ebde4a5

Browse files
committed
[asan] Fix and report the mem access start addr instead of poisoned addr
ACCESS_MEMORY_RANGE defined in asan_interceptors_memintrinsics.h reports the poisoned address (__bad), instead of the start address (__offset) during a memory access to ReportGenericError. We can determine that the latter (__offset) is the intended interpretation, as most error descriptions are decided by treating the given address as a start address (for example, see: PrintAccessAndVarIntersection in asan_descriptions.cpp, which decides whether a variable underflows or overflows depending on the given addr and access_size). GCC also uses the latter interpretation. For instance, in buffer overflows, it appears to do its own processing, and will report the start address of an overflowing read to ASan. This is in contrast to Clang, which uses __asan_memcpy directly. This patch fixes the above issue. Existing tests previously assumed and check for the former incorrect behaviour. The error descriptions in those tests have thus been corrected.
1 parent a161268 commit ebde4a5

14 files changed

+20
-20
lines changed

compiler-rt/lib/asan/asan_interceptors_memintrinsics.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ struct AsanInterceptorContext {
7474
} \
7575
if (!suppressed) { \
7676
GET_CURRENT_PC_BP_SP; \
77-
ReportGenericError(pc, bp, sp, __bad, isWrite, __size, 0, false); \
77+
ReportGenericError(pc, bp, sp, __offset, isWrite, __size, 0, false); \
7878
} \
7979
} \
8080
} while (0)

compiler-rt/test/asan/TestCases/wild_pointer.cpp renamed to compiler-rt/test/asan/TestCases/heap-overflow-large-read.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,22 +11,22 @@
1111
int main() {
1212
char *p = new char;
1313
char *dest = new char;
14-
const size_t offset = 0x4567890123456789;
14+
const size_t size = 0x4567890123456789;
1515

1616
// The output here needs to match the output from the sanitizer runtime,
1717
// which includes 0x and prints hex in lower case.
1818
//
1919
// On Windows, %p omits %0x and prints hex characters in upper case,
2020
// so we use PRIxPTR instead of %p.
2121
fprintf(stderr, "Expected bad addr: %#" PRIxPTR "\n",
22-
reinterpret_cast<uintptr_t>(p + offset));
22+
reinterpret_cast<uintptr_t>(p));
2323
// Flush it so the output came out before the asan report.
2424
fflush(stderr);
2525

26-
memmove(dest, p, offset);
26+
memmove(dest, p, size);
2727
return 0;
2828
}
2929

3030
// CHECK: Expected bad addr: [[ADDR:0x[0-9,a-f]+]]
31-
// CHECK: AddressSanitizer: unknown-crash on address [[ADDR]]
32-
// CHECK: Address [[ADDR]] is a wild pointer inside of access range of size 0x4567890123456789
31+
// CHECK: AddressSanitizer: heap-buffer-overflow on address [[ADDR]]
32+
// CHECK: READ of size 5001116549197948809 at [[ADDR]] thread T0

compiler-rt/test/asan/TestCases/strcasestr-1.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ int main(int argc, char **argv) {
1919
char s1[4] = "abC";
2020
__asan_poison_memory_region ((char *)&s1[2], 2);
2121
r = strcasestr(s1, s2);
22-
// CHECK:'s1'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
22+
// CHECK:'s1'{{.*}} <== Memory access at offset {{[0-9]+}} is inside this variable
2323
assert(r == s1 + 2);
2424
return 0;
2525
}

compiler-rt/test/asan/TestCases/strcasestr-2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ int main(int argc, char **argv) {
2020
__asan_poison_memory_region ((char *)&s2[2], 2);
2121
r = strcasestr(s1, s2);
2222
assert(r == 0);
23-
// CHECK:'s2'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
23+
// CHECK:'s2'{{.*}} <== Memory access at offset {{[0-9]+}} is inside this variable
2424
return 0;
2525
}

compiler-rt/test/asan/TestCases/strcspn-1.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ int main(int argc, char **argv) {
1414
char s1[4] = "caB";
1515
__asan_poison_memory_region ((char *)&s1[2], 2);
1616
r = strcspn(s1, s2);
17-
// CHECK:'s1'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
17+
// CHECK:'s1'{{.*}} <== Memory access at offset {{[0-9]+}} is inside this variable
1818
assert(r == 1);
1919
return 0;
2020
}

compiler-rt/test/asan/TestCases/strcspn-2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ int main(int argc, char **argv) {
1414
char s2[4] = "abc";
1515
__asan_poison_memory_region ((char *)&s2[2], 2);
1616
r = strcspn(s1, s2);
17-
// CHECK:'s2'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
17+
// CHECK:'s2'{{.*}} <== Memory access at offset {{[0-9]+}} is inside this variable
1818
assert(r == 0);
1919
return 0;
2020
}

compiler-rt/test/asan/TestCases/strpbrk-1.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ int main(int argc, char **argv) {
1414
char s1[4] = "cab";
1515
__asan_poison_memory_region ((char *)&s1[2], 2);
1616
r = strpbrk(s1, s2);
17-
// CHECK:'s1'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
17+
// CHECK:'s1'{{.*}} <== Memory access at offset {{[0-9]+}} is inside this variable
1818
assert(r == s1 + 1);
1919
return 0;
2020
}

compiler-rt/test/asan/TestCases/strpbrk-2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ int main(int argc, char **argv) {
1414
char s2[4] = "bca";
1515
__asan_poison_memory_region ((char *)&s2[2], 2);
1616
r = strpbrk(s1, s2);
17-
// CHECK:'s2'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
17+
// CHECK:'s2'{{.*}} <== Memory access at offset {{[0-9]+}} is inside this variable
1818
assert(r == s1);
1919
return 0;
2020
}

compiler-rt/test/asan/TestCases/strspn-1.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ int main(int argc, char **argv) {
1414
char s1[4] = "acb";
1515
__asan_poison_memory_region ((char *)&s1[2], 2);
1616
r = strspn(s1, s2);
17-
// CHECK:'s1'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
17+
// CHECK:'s1'{{.*}} <== Memory access at offset {{[0-9]+}} is inside this variable
1818
assert(r == 1);
1919
return 0;
2020
}

0 commit comments

Comments
 (0)