1 //===-- asan_mem_test.cc --------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is a part of AddressSanitizer, an address sanity checker.
12 //===----------------------------------------------------------------------===//
13 #include "asan_test_utils.h"
16 void MemSetOOBTestTemplate(size_t length
) {
17 if (length
== 0) return;
18 size_t size
= Ident(sizeof(T
) * length
);
19 T
*array
= Ident((T
*)malloc(size
));
20 int element
= Ident(42);
22 void *(*MEMSET
)(void *s
, int c
, size_t n
) = Ident(memset
);
23 // memset interval inside array
24 MEMSET(array
, element
, size
);
25 MEMSET(array
, element
, size
- 1);
26 MEMSET(array
+ length
- 1, element
, sizeof(T
));
27 MEMSET(array
, element
, 1);
30 MEMSET(array
- 10, element
, zero
);
31 MEMSET(array
- 1, element
, zero
);
32 MEMSET(array
, element
, zero
);
33 MEMSET(array
+ length
, 0, zero
);
34 MEMSET(array
+ length
+ 1, 0, zero
);
36 // try to memset bytes to the right of array
37 EXPECT_DEATH(MEMSET(array
, 0, size
+ 1),
38 RightOOBWriteMessage(0));
39 EXPECT_DEATH(MEMSET((char*)(array
+ length
) - 1, element
, 6),
40 RightOOBWriteMessage(0));
41 EXPECT_DEATH(MEMSET(array
+ 1, element
, size
+ sizeof(T
)),
42 RightOOBWriteMessage(0));
43 // whole interval is to the right
44 EXPECT_DEATH(MEMSET(array
+ length
+ 1, 0, 10),
45 RightOOBWriteMessage(sizeof(T
)));
47 // try to memset bytes to the left of array
48 EXPECT_DEATH(MEMSET((char*)array
- 1, element
, size
),
49 LeftOOBWriteMessage(1));
50 EXPECT_DEATH(MEMSET((char*)array
- 5, 0, 6),
51 LeftOOBWriteMessage(5));
53 // Large OOB, we find it only if the redzone is large enough.
54 EXPECT_DEATH(memset(array
- 5, element
, size
+ 5 * sizeof(T
)),
55 LeftOOBWriteMessage(5 * sizeof(T
)));
57 // whole interval is to the left
58 EXPECT_DEATH(MEMSET(array
- 2, 0, sizeof(T
)),
59 LeftOOBWriteMessage(2 * sizeof(T
)));
61 // try to memset bytes both to the left & to the right
62 EXPECT_DEATH(MEMSET((char*)array
- 2, element
, size
+ 4),
63 LeftOOBWriteMessage(2));
68 TEST(AddressSanitizer
, MemSetOOBTest
) {
69 MemSetOOBTestTemplate
<char>(100);
70 MemSetOOBTestTemplate
<int>(5);
71 MemSetOOBTestTemplate
<double>(256);
72 // We can test arrays of structres/classes here, but what for?
75 // Try to allocate two arrays of 'size' bytes that are near each other.
76 // Strictly speaking we are not guaranteed to find such two pointers,
77 // but given the structure of asan's allocator we will.
78 static bool AllocateTwoAdjacentArrays(char **x1
, char **x2
, size_t size
) {
81 for (size_t i
= 0; i
< 1000U && !res
; i
++) {
82 v
.push_back(reinterpret_cast<uintptr_t>(new char[size
]));
84 sort(v
.begin(), v
.end());
85 for (size_t j
= 1; j
< v
.size(); j
++) {
86 assert(v
[j
] > v
[j
-1]);
87 if ((size_t)(v
[j
] - v
[j
-1]) < size
* 2) {
88 *x2
= reinterpret_cast<char*>(v
[j
]);
89 *x1
= reinterpret_cast<char*>(v
[j
-1]);
96 for (size_t i
= 0; i
< v
.size(); i
++) {
97 char *p
= reinterpret_cast<char *>(v
[i
]);
98 if (res
&& p
== *x1
) continue;
99 if (res
&& p
== *x2
) continue;
105 TEST(AddressSanitizer
, LargeOOBInMemset
) {
106 for (size_t size
= 200; size
< 100000; size
+= size
/ 2) {
108 if (!Ident(AllocateTwoAdjacentArrays
)(&x1
, &x2
, size
))
110 // fprintf(stderr, " large oob memset: %p %p %zd\n", x1, x2, size);
111 // Do a memset on x1 with huge out-of-bound access that will end up in x2.
112 EXPECT_DEATH(Ident(memset
)(x1
, 0, size
* 2),
113 "is located 0 bytes to the right");
118 assert(0 && "Did not find two adjacent malloc-ed pointers");
121 // Same test for memcpy and memmove functions
122 template <typename T
, class M
>
123 void MemTransferOOBTestTemplate(size_t length
) {
124 if (length
== 0) return;
125 size_t size
= Ident(sizeof(T
) * length
);
126 T
*src
= Ident((T
*)malloc(size
));
127 T
*dest
= Ident((T
*)malloc(size
));
130 // valid transfer of bytes between arrays
131 M::transfer(dest
, src
, size
);
132 M::transfer(dest
+ 1, src
, size
- sizeof(T
));
133 M::transfer(dest
, src
+ length
- 1, sizeof(T
));
134 M::transfer(dest
, src
, 1);
136 // transfer zero bytes
137 M::transfer(dest
- 1, src
, 0);
138 M::transfer(dest
+ length
, src
, zero
);
139 M::transfer(dest
, src
- 1, zero
);
140 M::transfer(dest
, src
, zero
);
142 // try to change mem to the right of dest
143 EXPECT_DEATH(M::transfer(dest
+ 1, src
, size
),
144 RightOOBWriteMessage(0));
145 EXPECT_DEATH(M::transfer((char*)(dest
+ length
) - 1, src
, 5),
146 RightOOBWriteMessage(0));
148 // try to change mem to the left of dest
149 EXPECT_DEATH(M::transfer(dest
- 2, src
, size
),
150 LeftOOBWriteMessage(2 * sizeof(T
)));
151 EXPECT_DEATH(M::transfer((char*)dest
- 3, src
, 4),
152 LeftOOBWriteMessage(3));
154 // try to access mem to the right of src
155 EXPECT_DEATH(M::transfer(dest
, src
+ 2, size
),
156 RightOOBReadMessage(0));
157 EXPECT_DEATH(M::transfer(dest
, (char*)(src
+ length
) - 3, 6),
158 RightOOBReadMessage(0));
160 // try to access mem to the left of src
161 EXPECT_DEATH(M::transfer(dest
, src
- 1, size
),
162 LeftOOBReadMessage(sizeof(T
)));
163 EXPECT_DEATH(M::transfer(dest
, (char*)src
- 6, 7),
164 LeftOOBReadMessage(6));
166 // Generally we don't need to test cases where both accessing src and writing
167 // to dest address to poisoned memory.
169 T
*big_src
= Ident((T
*)malloc(size
* 2));
170 T
*big_dest
= Ident((T
*)malloc(size
* 2));
171 // try to change mem to both sides of dest
172 EXPECT_DEATH(M::transfer(dest
- 1, big_src
, size
* 2),
173 LeftOOBWriteMessage(sizeof(T
)));
174 // try to access mem to both sides of src
175 EXPECT_DEATH(M::transfer(big_dest
, src
- 2, size
* 2),
176 LeftOOBReadMessage(2 * sizeof(T
)));
184 class MemCpyWrapper
{
186 static void* transfer(void *to
, const void *from
, size_t size
) {
187 return Ident(memcpy
)(to
, from
, size
);
191 TEST(AddressSanitizer
, MemCpyOOBTest
) {
192 MemTransferOOBTestTemplate
<char, MemCpyWrapper
>(100);
193 MemTransferOOBTestTemplate
<int, MemCpyWrapper
>(1024);
196 class MemMoveWrapper
{
198 static void* transfer(void *to
, const void *from
, size_t size
) {
199 return Ident(memmove
)(to
, from
, size
);
203 TEST(AddressSanitizer
, MemMoveOOBTest
) {
204 MemTransferOOBTestTemplate
<char, MemMoveWrapper
>(100);
205 MemTransferOOBTestTemplate
<int, MemMoveWrapper
>(1024);
209 TEST(AddressSanitizer
, MemCmpOOBTest
) {
210 size_t size
= Ident(100);
211 char *s1
= MallocAndMemsetString(size
);
212 char *s2
= MallocAndMemsetString(size
);
213 // Normal memcmp calls.
214 Ident(memcmp(s1
, s2
, size
));
215 Ident(memcmp(s1
+ size
- 1, s2
+ size
- 1, 1));
216 Ident(memcmp(s1
- 1, s2
- 1, 0));
217 // One of arguments points to not allocated memory.
218 EXPECT_DEATH(Ident(memcmp
)(s1
- 1, s2
, 1), LeftOOBReadMessage(1));
219 EXPECT_DEATH(Ident(memcmp
)(s1
, s2
- 1, 1), LeftOOBReadMessage(1));
220 EXPECT_DEATH(Ident(memcmp
)(s1
+ size
, s2
, 1), RightOOBReadMessage(0));
221 EXPECT_DEATH(Ident(memcmp
)(s1
, s2
+ size
, 1), RightOOBReadMessage(0));
222 // Hit unallocated memory and die.
223 EXPECT_DEATH(Ident(memcmp
)(s1
+ 1, s2
+ 1, size
), RightOOBReadMessage(0));
224 EXPECT_DEATH(Ident(memcmp
)(s1
+ size
- 1, s2
, 2), RightOOBReadMessage(0));
225 // Zero bytes are not terminators and don't prevent from OOB.
228 EXPECT_DEATH(Ident(memcmp
)(s1
, s2
, size
+ 1), RightOOBReadMessage(0));
230 // Even if the buffers differ in the first byte, we still assume that
231 // memcmp may access the whole buffer and thus reporting the overflow here:
234 EXPECT_DEATH(Ident(memcmp
)(s1
, s2
, size
+ 1), RightOOBReadMessage(0));