1 | // Test that large memset/memcpy/memmove check the entire range. |
2 | |
3 | // RUN: %clangxx_asan -O0 -DTEST_MEMSET %s -o %t && not %run %t 2>&1 | \ |
4 | // RUN: FileCheck %s --check-prefix=CHECK-MEMSET |
5 | // RUN: %clangxx_asan -O1 -DTEST_MEMSET %s -o %t && not %run %t 2>&1 | \ |
6 | // RUN: FileCheck %s --check-prefix=CHECK-MEMSET |
7 | // RUN: %clangxx_asan -O2 -DTEST_MEMSET %s -o %t && not %run %t 2>&1 | \ |
8 | // RUN: FileCheck %s --check-prefix=CHECK-MEMSET |
9 | // RUN: %clangxx_asan -O3 -DTEST_MEMSET %s -o %t && not %run %t 2>&1 | \ |
10 | // RUN: FileCheck %s --check-prefix=CHECK-MEMSET |
11 | |
12 | // RUN: %clangxx_asan -O0 -DTEST_MEMCPY %s -o %t && not %run %t 2>&1 | \ |
13 | // RUN: FileCheck %s --check-prefix=CHECK-MEMCPY |
14 | // RUN: %clangxx_asan -O1 -DTEST_MEMCPY %s -o %t && not %run %t 2>&1 | \ |
15 | // RUN: FileCheck %s --check-prefix=CHECK-MEMCPY |
16 | // RUN: %clangxx_asan -O2 -DTEST_MEMCPY %s -o %t && not %run %t 2>&1 | \ |
17 | // RUN: FileCheck %s --check-prefix=CHECK-MEMCPY |
18 | // RUN: %clangxx_asan -O3 -DTEST_MEMCPY %s -o %t && not %run %t 2>&1 | \ |
19 | // RUN: FileCheck %s --check-prefix=CHECK-MEMCPY |
20 | |
21 | // RUN: %clangxx_asan -O0 -DTEST_MEMMOVE %s -o %t && not %run %t 2>&1 | \ |
22 | // RUN: FileCheck %s --check-prefix=CHECK-MEMMOVE |
23 | // RUN: %clangxx_asan -O1 -DTEST_MEMMOVE %s -o %t && not %run %t 2>&1 | \ |
24 | // RUN: FileCheck %s --check-prefix=CHECK-MEMMOVE |
25 | // RUN: %clangxx_asan -O2 -DTEST_MEMMOVE %s -o %t && not %run %t 2>&1 | \ |
26 | // RUN: FileCheck %s --check-prefix=CHECK-MEMMOVE |
27 | // RUN: %clangxx_asan -O3 -DTEST_MEMMOVE %s -o %t && not %run %t 2>&1 | \ |
28 | // RUN: FileCheck %s --check-prefix=CHECK-MEMMOVE |
29 | |
30 | // RUN: %clangxx_asan -O2 -DTEST_MEMCPY_SIZE_OVERFLOW %s -o %t && not %run %t 2>&1 | \ |
31 | // RUN: FileCheck %s --check-prefix=CHECK-MEMCPY_SIZE_OVERFLOW |
32 | |
33 | #include <assert.h> |
34 | #include <string.h> |
35 | #include <stdlib.h> |
36 | #include <stdio.h> |
37 | |
38 | #include <sanitizer/asan_interface.h> |
39 | |
40 | typedef void *(*memcpy_t)(void *, const void *, size_t); |
41 | |
42 | int main(int argc, char **argv) { |
43 | char * volatile p = (char *)malloc(size: 3000); |
44 | __asan_poison_memory_region(addr: p + 512, size: 32); |
45 | #if defined(TEST_MEMSET) |
46 | memset(p, 0, 3000); |
47 | assert(p[1] == 0); |
48 | // CHECK-MEMSET: AddressSanitizer: use-after-poison on address |
49 | // CHECK-MEMSET: in {{.*}}memset |
50 | #else |
51 | char * volatile q = (char *)malloc(size: 3000); |
52 | #if defined(TEST_MEMCPY) |
53 | memcpy(q, p, 3000); |
54 | // CHECK-MEMCPY: AddressSanitizer: use-after-poison on address |
55 | // On Mac, memmove and memcpy are the same. Accept either one. |
56 | // CHECK-MEMCPY: in {{.*(memmove|memcpy)}} |
57 | #elif defined(TEST_MEMMOVE) |
58 | memmove(q, p, 3000); |
59 | // CHECK-MEMMOVE: AddressSanitizer: use-after-poison on address |
60 | // CHECK-MEMMOVE: in {{.*(memmove|memcpy)}} |
61 | #elif defined(TEST_MEMCPY_SIZE_OVERFLOW) |
62 | volatile memcpy_t my_memcpy = &memcpy; |
63 | my_memcpy(p, q, -argc); |
64 | // CHECK-MEMCPY_SIZE_OVERFLOW: AddressSanitizer: negative-size-param: (size=-1) |
65 | #endif |
66 | assert(q[1] == 0); |
67 | free(ptr: q); |
68 | #endif |
69 | free(ptr: p); |
70 | return 0; |
71 | } |
72 | |