Skip to content

Commit 43e577e

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 43e577e

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
}

compiler-rt/test/asan/TestCases/strspn-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[5] = "abcd";
1515
__asan_poison_memory_region ((char *)&s2[3], 2);
1616
r = strspn(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 >= 2);
1919
return 0;
2020
}

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

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

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

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

compiler-rt/test/asan/TestCases/strtok.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ void test1() {
3535
char token_delimiter[2] = "b";
3636
__asan_poison_memory_region ((char *)&token_delimiter[1], 2);
3737
token = strtok(s, token_delimiter);
38-
// CHECK1: 'token_delimiter'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
38+
// CHECK1: 'token_delimiter'{{.*}} <== Memory access at offset {{[0-9]+}} is inside this variable
3939
}
4040

4141
// Check that we find overflows in the delimiters on the second call (str == NULL)
@@ -48,7 +48,7 @@ void test2() {
4848
assert(strcmp(token, "a") == 0);
4949
__asan_poison_memory_region ((char *)&token_delimiter[1], 2);
5050
token = strtok(NULL, token_delimiter);
51-
// CHECK2: 'token_delimiter'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
51+
// CHECK2: 'token_delimiter'{{.*}} <== Memory access at offset {{[0-9]+}} is inside this variable
5252
}
5353

5454
// Check that we find overflows in the string (only on the first call) with strict_string_checks.
@@ -58,7 +58,7 @@ void test3() {
5858
char token_delimiter[2] = "b";
5959
__asan_poison_memory_region ((char *)&s[3], 2);
6060
token = strtok(s, token_delimiter);
61-
// CHECK3: 's'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
61+
// CHECK3: 's'{{.*}} <== Memory access at offset {{[0-9]+}} is inside this variable
6262
}
6363

6464
// Check that we do not crash when strtok returns NULL with strict_string_checks.
@@ -78,7 +78,7 @@ void test5() {
7878
__asan_poison_memory_region ((char *)&s[2], 2);
7979
__asan_poison_memory_region ((char *)&token_delimiter[1], 2);
8080
token = strtok(s, token_delimiter);
81-
// CHECK5: 's'{{.*}} <== Memory access at offset {{[0-9]+}} partially overflows this variable
81+
// CHECK5: 's'{{.*}} <== Memory access at offset {{[0-9]+}} is inside this variable
8282
}
8383

8484
// Check that we find overflows in the delimiters (only on the first call) with !strict_string_checks.

0 commit comments

Comments
 (0)