xref: /llvm-project/compiler-rt/lib/asan/tests/asan_str_test.cpp (revision 9f3d083c4963fcd164fc48e326e5967e6395f28a)
1 //=-- asan_str_test.cpp ---------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file is a part of AddressSanitizer, an address sanity checker.
10 //
11 //===----------------------------------------------------------------------===//
12 #include "asan_test_utils.h"
13 
14 #if defined(__APPLE__)
15 #include <AvailabilityMacros.h>  // For MAC_OS_X_VERSION_*
16 #endif
17 
18 // Used for string functions tests
19 static char global_string[] = "global";
20 static size_t global_string_length = 6;
21 
22 const char kStackReadUnderflow[] =
23 #if !GTEST_USES_SIMPLE_RE
24     ASAN_PCRE_DOTALL
25     "READ.*"
26 #endif
27     "underflows this variable";
28 const char kStackReadOverflow[] =
29 #if !GTEST_USES_SIMPLE_RE
30     ASAN_PCRE_DOTALL
31     "READ.*"
32 #endif
33     "overflows this variable";
34 
35 namespace {
36 enum class OOBKind {
37   Heap,
38   Stack,
39   Global,
40 };
41 
42 std::string LeftOOBReadMessage(OOBKind oob_kind, int oob_distance) {
43   return oob_kind == OOBKind::Stack ? kStackReadUnderflow
44                                     : ::LeftOOBReadMessage(oob_distance);
45 }
46 
47 std::string RightOOBReadMessage(OOBKind oob_kind, int oob_distance) {
48   return oob_kind == OOBKind::Stack ? kStackReadOverflow
49                                     : ::RightOOBReadMessage(oob_distance);
50 }
51 }  // namespace
52 
53 // Input to a test is a zero-terminated string str with given length
54 // Accesses to the bytes before and after str
55 // are presumed to produce OOB errors
56 void StrLenOOBTestTemplate(char *str, size_t length, OOBKind oob_kind) {
57   // Normal strlen calls
58   EXPECT_EQ(strlen(str), length);
59   if (length > 0) {
60     EXPECT_EQ(length - 1, strlen(str + 1));
61     EXPECT_EQ(0U, strlen(str + length));
62   }
63   // Arg of strlen is not malloced, OOB access
64   if (oob_kind != OOBKind::Global) {
65     // We don't insert RedZones before global variables
66     EXPECT_DEATH(Ident(strlen(str - 1)), LeftOOBReadMessage(oob_kind, 1));
67     EXPECT_DEATH(Ident(strlen(str - 5)), LeftOOBReadMessage(oob_kind, 5));
68   }
69   EXPECT_DEATH(Ident(strlen(str + length + 1)),
70                RightOOBReadMessage(oob_kind, 0));
71   // Overwrite terminator
72   str[length] = 'a';
73   // String is not zero-terminated, strlen will lead to OOB access
74   EXPECT_DEATH(Ident(strlen(str)), RightOOBReadMessage(oob_kind, 0));
75   EXPECT_DEATH(Ident(strlen(str + length)), RightOOBReadMessage(oob_kind, 0));
76   // Restore terminator
77   str[length] = 0;
78 }
79 TEST(AddressSanitizer, StrLenOOBTest) {
80   // Check heap-allocated string
81   size_t length = Ident(10);
82   char *heap_string = Ident((char*)malloc(length + 1));
83   char stack_string[10 + 1];
84   break_optimization(&stack_string);
85   for (size_t i = 0; i < length; i++) {
86     heap_string[i] = 'a';
87     stack_string[i] = 'b';
88   }
89   heap_string[length] = 0;
90   stack_string[length] = 0;
91   StrLenOOBTestTemplate(heap_string, length, OOBKind::Heap);
92   StrLenOOBTestTemplate(stack_string, length, OOBKind::Stack);
93   StrLenOOBTestTemplate(global_string, global_string_length, OOBKind::Global);
94   free(heap_string);
95 }
96 
97 // 32-bit android libc++-based NDK toolchain links wcslen statically, disabling
98 // the interceptor.
99 #if !defined(__ANDROID__) || defined(__LP64__)
100 TEST(AddressSanitizer, WcsLenTest) {
101   EXPECT_EQ(0U, wcslen(Ident(L"")));
102   size_t hello_len = 13;
103   size_t hello_size = (hello_len + 1) * sizeof(wchar_t);
104   EXPECT_EQ(hello_len, wcslen(Ident(L"Hello, World!")));
105   wchar_t *heap_string = Ident((wchar_t*)malloc(hello_size));
106   memcpy(heap_string, L"Hello, World!", hello_size);
107   EXPECT_EQ(hello_len, Ident(wcslen(heap_string)));
108   EXPECT_DEATH(Ident(wcslen(heap_string + 14)), RightOOBReadMessage(0));
109   free(heap_string);
110 }
111 #endif
112 
113 // This test fails on MinGW-w64 because it still ships a static copy of strnlen
114 // despite it being available from UCRT.
115 #if defined(__MINGW32__)
116 #  define MAYBE_StrNLenOOBTest DISABLED_StrNLenOOBTest
117 #else
118 #  define MAYBE_StrNLenOOBTest StrNLenOOBTest
119 #endif
120 
121 #if SANITIZER_TEST_HAS_STRNLEN
122 TEST(AddressSanitizer, MAYBE_StrNLenOOBTest) {
123   size_t size = Ident(123);
124   char *str = MallocAndMemsetString(size);
125   // Normal strnlen calls.
126   Ident(strnlen(str - 1, 0));
127   Ident(strnlen(str, size));
128   Ident(strnlen(str + size - 1, 1));
129   str[size - 1] = '\0';
130   Ident(strnlen(str, 2 * size));
131   // Argument points to not allocated memory.
132   EXPECT_DEATH(Ident(strnlen(str - 1, 1)), LeftOOBReadMessage(1));
133   EXPECT_DEATH(Ident(strnlen(str + size, 1)), RightOOBReadMessage(0));
134   // Overwrite the terminating '\0' and hit unallocated memory.
135   str[size - 1] = 'z';
136   EXPECT_DEATH(Ident(strnlen(str, size + 1)), RightOOBReadMessage(0));
137   free(str);
138 }
139 #endif  // SANITIZER_TEST_HAS_STRNLEN
140 
141 // This test fails with the WinASan dynamic runtime because we fail to intercept
142 // strdup.
143 #if (defined(_MSC_VER) && defined(_DLL)) || defined(__MINGW32__)
144 #  define MAYBE_StrDupOOBTest DISABLED_StrDupOOBTest
145 #else
146 #  define MAYBE_StrDupOOBTest StrDupOOBTest
147 #endif
148 
149 TEST(AddressSanitizer, MAYBE_StrDupOOBTest) {
150   size_t size = Ident(42);
151   char *str = MallocAndMemsetString(size);
152   char *new_str;
153   // Normal strdup calls.
154   str[size - 1] = '\0';
155   new_str = strdup(str);
156   free(new_str);
157   new_str = strdup(str + size - 1);
158   free(new_str);
159   // Argument points to not allocated memory.
160   EXPECT_DEATH(Ident(strdup(str - 1)), LeftOOBReadMessage(1));
161   EXPECT_DEATH(Ident(strdup(str + size)), RightOOBReadMessage(0));
162   // Overwrite the terminating '\0' and hit unallocated memory.
163   str[size - 1] = 'z';
164   EXPECT_DEATH(Ident(strdup(str)), RightOOBReadMessage(0));
165   free(str);
166 }
167 
168 #if SANITIZER_TEST_HAS_STRNDUP
169 TEST(AddressSanitizer, MAYBE_StrNDupOOBTest) {
170   size_t size = Ident(42);
171   char *str = MallocAndMemsetString(size);
172   char *new_str;
173   // Normal strndup calls.
174   str[size - 1] = '\0';
175   new_str = strndup(str, size - 13);
176   free(new_str);
177   new_str = strndup(str + size - 1, 13);
178   free(new_str);
179   // Argument points to not allocated memory.
180   EXPECT_DEATH(Ident(strndup(str - 1, 13)), LeftOOBReadMessage(1));
181   EXPECT_DEATH(Ident(strndup(str + size, 13)), RightOOBReadMessage(0));
182   // Overwrite the terminating '\0' and hit unallocated memory.
183   str[size - 1] = 'z';
184   EXPECT_DEATH(Ident(strndup(str, size + 13)), RightOOBReadMessage(0));
185   // Check handling of non 0 terminated strings.
186   Ident(new_str = strndup(str + size - 1, 0));
187   free(new_str);
188   Ident(new_str = strndup(str + size - 1, 1));
189   free(new_str);
190   EXPECT_DEATH(Ident(strndup(str + size - 1, 2)), RightOOBReadMessage(0));
191   free(str);
192 }
193 #endif // SANITIZER_TEST_HAS_STRNDUP
194 
195 TEST(AddressSanitizer, StrCpyOOBTest) {
196   size_t to_size = Ident(30);
197   size_t from_size = Ident(6);  // less than to_size
198   char *to = Ident((char*)malloc(to_size));
199   char *from = Ident((char*)malloc(from_size));
200   // Normal strcpy calls.
201   strcpy(from, "hello");
202   strcpy(to, from);
203   strcpy(to + to_size - from_size, from);
204   // Length of "from" is too small.
205   EXPECT_DEATH(Ident(strcpy(from, "hello2")), RightOOBWriteMessage(0));
206   // "to" or "from" points to not allocated memory.
207   EXPECT_DEATH(Ident(strcpy(to - 1, from)), LeftOOBWriteMessage(1));
208   EXPECT_DEATH(Ident(strcpy(to, from - 1)), LeftOOBReadMessage(1));
209   EXPECT_DEATH(Ident(strcpy(to, from + from_size)), RightOOBReadMessage(0));
210   EXPECT_DEATH(Ident(strcpy(to + to_size, from)), RightOOBWriteMessage(0));
211   // Overwrite the terminating '\0' character and hit unallocated memory.
212   from[from_size - 1] = '!';
213   EXPECT_DEATH(Ident(strcpy(to, from)), RightOOBReadMessage(0));
214   free(to);
215   free(from);
216 }
217 
218 TEST(AddressSanitizer, StrNCpyOOBTest) {
219   size_t to_size = Ident(20);
220   size_t from_size = Ident(6);  // less than to_size
221   char *to = Ident((char*)malloc(to_size));
222   // From is a zero-terminated string "hello\0" of length 6
223   char *from = Ident((char*)malloc(from_size));
224   strcpy(from, "hello");
225   // copy 0 bytes
226   strncpy(to, from, 0);
227   strncpy(to - 1, from - 1, 0);
228   // normal strncpy calls
229   strncpy(to, from, from_size);
230   strncpy(to, from, to_size);
231   strncpy(to, from + from_size - 1, to_size);
232   strncpy(to + to_size - 1, from, 1);
233   // One of {to, from} points to not allocated memory
234   EXPECT_DEATH(Ident(strncpy(to, from - 1, from_size)),
235                LeftOOBReadMessage(1));
236   EXPECT_DEATH(Ident(strncpy(to - 1, from, from_size)),
237                LeftOOBWriteMessage(1));
238   EXPECT_DEATH(Ident(strncpy(to, from + from_size, 1)),
239                RightOOBReadMessage(0));
240   EXPECT_DEATH(Ident(strncpy(to + to_size, from, 1)),
241                RightOOBWriteMessage(0));
242   // Length of "to" is too small
243   EXPECT_DEATH(Ident(strncpy(to + to_size - from_size + 1, from, from_size)),
244                RightOOBWriteMessage(0));
245   EXPECT_DEATH(Ident(strncpy(to + 1, from, to_size)),
246                RightOOBWriteMessage(0));
247   // Overwrite terminator in from
248   from[from_size - 1] = '!';
249   // normal strncpy call
250   strncpy(to, from, from_size);
251   // Length of "from" is too small
252   EXPECT_DEATH(Ident(strncpy(to, from, to_size)),
253                RightOOBReadMessage(0));
254   free(to);
255   free(from);
256 }
257 
258 // Users may have different definitions of "strchr" and "index", so provide
259 // function pointer typedefs and overload RunStrChrTest implementation.
260 // We can't use macro for RunStrChrTest body here, as this macro would
261 // confuse EXPECT_DEATH gtest macro.
262 typedef char*(*PointerToStrChr1)(const char*, int);
263 typedef char*(*PointerToStrChr2)(char*, int);
264 
265 template<typename StrChrFn>
266 static void RunStrChrTestImpl(StrChrFn *StrChr) {
267   size_t size = Ident(100);
268   char *str = MallocAndMemsetString(size);
269   str[10] = 'q';
270   str[11] = '\0';
271   EXPECT_EQ(str, StrChr(str, 'z'));
272   EXPECT_EQ(str + 10, StrChr(str, 'q'));
273   EXPECT_EQ(NULL, StrChr(str, 'a'));
274   // StrChr argument points to not allocated memory.
275   EXPECT_DEATH(Ident(StrChr(str - 1, 'z')), LeftOOBReadMessage(1));
276   EXPECT_DEATH(Ident(StrChr(str + size, 'z')), RightOOBReadMessage(0));
277   // Overwrite the terminator and hit not allocated memory.
278   str[11] = 'z';
279   EXPECT_DEATH(Ident(StrChr(str, 'a')), RightOOBReadMessage(0));
280   free(str);
281 }
282 
283 // Prefer to use the standard signature if both are available.
284 UNUSED static void RunStrChrTest(PointerToStrChr1 StrChr, ...) {
285   RunStrChrTestImpl(StrChr);
286 }
287 UNUSED static void RunStrChrTest(PointerToStrChr2 StrChr, int) {
288   RunStrChrTestImpl(StrChr);
289 }
290 
291 TEST(AddressSanitizer, StrChrAndIndexOOBTest) {
292   RunStrChrTest(&strchr, 0);
293 // No index() on Windows and on Android L.
294 #if !defined(_WIN32) && !defined(__ANDROID__)
295   RunStrChrTest(&index, 0);
296 #endif
297 }
298 
299 TEST(AddressSanitizer, StrCmpAndFriendsLogicTest) {
300   // strcmp
301   EXPECT_EQ(0, strcmp("", ""));
302   EXPECT_EQ(0, strcmp("abcd", "abcd"));
303   EXPECT_GT(0, strcmp("ab", "ac"));
304   EXPECT_GT(0, strcmp("abc", "abcd"));
305   EXPECT_LT(0, strcmp("acc", "abc"));
306   EXPECT_LT(0, strcmp("abcd", "abc"));
307 
308   // strncmp
309   EXPECT_EQ(0, strncmp("a", "b", 0));
310   EXPECT_EQ(0, strncmp("abcd", "abcd", 10));
311   EXPECT_EQ(0, strncmp("abcd", "abcef", 3));
312   EXPECT_GT(0, strncmp("abcde", "abcfa", 4));
313   EXPECT_GT(0, strncmp("a", "b", 5));
314   EXPECT_GT(0, strncmp("bc", "bcde", 4));
315   EXPECT_LT(0, strncmp("xyz", "xyy", 10));
316   EXPECT_LT(0, strncmp("baa", "aaa", 1));
317   EXPECT_LT(0, strncmp("zyx", "", 2));
318 
319 #if !defined(_WIN32)  // no str[n]casecmp on Windows.
320   // strcasecmp
321   EXPECT_EQ(0, strcasecmp("", ""));
322   EXPECT_EQ(0, strcasecmp("zzz", "zzz"));
323   EXPECT_EQ(0, strcasecmp("abCD", "ABcd"));
324   EXPECT_GT(0, strcasecmp("aB", "Ac"));
325   EXPECT_GT(0, strcasecmp("ABC", "ABCd"));
326   EXPECT_LT(0, strcasecmp("acc", "abc"));
327   EXPECT_LT(0, strcasecmp("ABCd", "abc"));
328 
329   // strncasecmp
330   EXPECT_EQ(0, strncasecmp("a", "b", 0));
331   EXPECT_EQ(0, strncasecmp("abCD", "ABcd", 10));
332   EXPECT_EQ(0, strncasecmp("abCd", "ABcef", 3));
333   EXPECT_GT(0, strncasecmp("abcde", "ABCfa", 4));
334   EXPECT_GT(0, strncasecmp("a", "B", 5));
335   EXPECT_GT(0, strncasecmp("bc", "BCde", 4));
336   EXPECT_LT(0, strncasecmp("xyz", "xyy", 10));
337   EXPECT_LT(0, strncasecmp("Baa", "aaa", 1));
338   EXPECT_LT(0, strncasecmp("zyx", "", 2));
339 #endif
340 
341   // memcmp
342   EXPECT_EQ(0, memcmp("a", "b", 0));
343   EXPECT_EQ(0, memcmp("ab\0c", "ab\0c", 4));
344   EXPECT_GT(0, memcmp("\0ab", "\0ac", 3));
345   EXPECT_GT(0, memcmp("abb\0", "abba", 4));
346   EXPECT_LT(0, memcmp("ab\0cd", "ab\0c\0", 5));
347   EXPECT_LT(0, memcmp("zza", "zyx", 3));
348 }
349 
350 typedef int(*PointerToStrCmp)(const char*, const char*);
351 void RunStrCmpTest(PointerToStrCmp StrCmp) {
352   size_t size = Ident(100);
353   int fill = 'o';
354   char *s1 = MallocAndMemsetString(size, fill);
355   char *s2 = MallocAndMemsetString(size, fill);
356   s1[size - 1] = '\0';
357   s2[size - 1] = '\0';
358   // Normal StrCmp calls
359   Ident(StrCmp(s1, s2));
360   Ident(StrCmp(s1, s2 + size - 1));
361   Ident(StrCmp(s1 + size - 1, s2 + size - 1));
362   // One of arguments points to not allocated memory.
363   EXPECT_DEATH(Ident(StrCmp)(s1 - 1, s2), LeftOOBReadMessage(1));
364   EXPECT_DEATH(Ident(StrCmp)(s1, s2 - 1), LeftOOBReadMessage(1));
365   EXPECT_DEATH(Ident(StrCmp)(s1 + size, s2), RightOOBReadMessage(0));
366   EXPECT_DEATH(Ident(StrCmp)(s1, s2 + size), RightOOBReadMessage(0));
367   // Hit unallocated memory and die.
368   s1[size - 1] = fill;
369   EXPECT_DEATH(Ident(StrCmp)(s1, s1), RightOOBReadMessage(0));
370   EXPECT_DEATH(Ident(StrCmp)(s1 + size - 1, s2), RightOOBReadMessage(0));
371   free(s1);
372   free(s2);
373 }
374 
375 TEST(AddressSanitizer, StrCmpOOBTest) {
376   RunStrCmpTest(&strcmp);
377 }
378 
379 #if !defined(_WIN32)  // no str[n]casecmp on Windows.
380 TEST(AddressSanitizer, StrCaseCmpOOBTest) {
381   RunStrCmpTest(&strcasecmp);
382 }
383 #endif
384 
385 typedef int(*PointerToStrNCmp)(const char*, const char*, size_t);
386 void RunStrNCmpTest(PointerToStrNCmp StrNCmp) {
387   size_t size = Ident(100);
388   char *s1 = MallocAndMemsetString(size);
389   char *s2 = MallocAndMemsetString(size);
390   s1[size - 1] = '\0';
391   s2[size - 1] = '\0';
392   // Normal StrNCmp calls
393   Ident(StrNCmp(s1, s2, size + 2));
394   s1[size - 1] = 'z';
395   s2[size - 1] = 'x';
396   Ident(StrNCmp(s1 + size - 2, s2 + size - 2, size));
397   s2[size - 1] = 'z';
398   Ident(StrNCmp(s1 - 1, s2 - 1, 0));
399   Ident(StrNCmp(s1 + size - 1, s2 + size - 1, 1));
400   // One of arguments points to not allocated memory.
401   EXPECT_DEATH(Ident(StrNCmp)(s1 - 1, s2, 1), LeftOOBReadMessage(1));
402   EXPECT_DEATH(Ident(StrNCmp)(s1, s2 - 1, 1), LeftOOBReadMessage(1));
403   EXPECT_DEATH(Ident(StrNCmp)(s1 + size, s2, 1), RightOOBReadMessage(0));
404   EXPECT_DEATH(Ident(StrNCmp)(s1, s2 + size, 1), RightOOBReadMessage(0));
405   // Hit unallocated memory and die.
406   EXPECT_DEATH(Ident(StrNCmp)(s1 + 1, s2 + 1, size), RightOOBReadMessage(0));
407   EXPECT_DEATH(Ident(StrNCmp)(s1 + size - 1, s2, 2), RightOOBReadMessage(0));
408   free(s1);
409   free(s2);
410 }
411 
412 TEST(AddressSanitizer, StrNCmpOOBTest) {
413   RunStrNCmpTest(&strncmp);
414 }
415 
416 #if !defined(_WIN32)  // no str[n]casecmp on Windows.
417 TEST(AddressSanitizer, StrNCaseCmpOOBTest) {
418   RunStrNCmpTest(&strncasecmp);
419 }
420 #endif
421 
422 TEST(AddressSanitizer, StrCatOOBTest) {
423   // strcat() reads strlen(to) bytes from |to| before concatenating.
424   size_t to_size = Ident(100);
425   char *to = MallocAndMemsetString(to_size);
426   to[0] = '\0';
427   size_t from_size = Ident(20);
428   char *from = MallocAndMemsetString(from_size);
429   from[from_size - 1] = '\0';
430   // Normal strcat calls.
431   strcat(to, from);
432   strcat(to, from);
433   strcat(to + from_size, from + from_size - 2);
434   // Passing an invalid pointer is an error even when concatenating an empty
435   // string.
436   EXPECT_DEATH(strcat(to - 1, from + from_size - 1), LeftOOBAccessMessage(1));
437   // One of arguments points to not allocated memory.
438   EXPECT_DEATH(strcat(to - 1, from), LeftOOBAccessMessage(1));
439   EXPECT_DEATH(strcat(to, from - 1), LeftOOBReadMessage(1));
440   EXPECT_DEATH(strcat(to, from + from_size), RightOOBReadMessage(0));
441 
442   // "from" is not zero-terminated.
443   from[from_size - 1] = 'z';
444   EXPECT_DEATH(strcat(to, from), RightOOBReadMessage(0));
445   from[from_size - 1] = '\0';
446   // "to" is too short to fit "from".
447   memset(to, 'z', to_size);
448   to[to_size - from_size + 1] = '\0';
449   EXPECT_DEATH(strcat(to, from), RightOOBWriteMessage(0));
450   // length of "to" is just enough.
451   strcat(to, from + 1);
452 
453   free(to);
454   free(from);
455 }
456 
457 TEST(AddressSanitizer, StrNCatOOBTest) {
458   // strncat() reads strlen(to) bytes from |to| before concatenating.
459   size_t to_size = Ident(100);
460   char *to = MallocAndMemsetString(to_size);
461   to[0] = '\0';
462   size_t from_size = Ident(20);
463   char *from = MallocAndMemsetString(from_size);
464   // Normal strncat calls.
465   strncat(to, from, 0);
466   strncat(to, from, from_size);
467   from[from_size - 1] = '\0';
468   strncat(to, from, 2 * from_size);
469   strncat(to, from + from_size - 1, 10);
470   // One of arguments points to not allocated memory.
471   EXPECT_DEATH(strncat(to - 1, from, 2), LeftOOBAccessMessage(1));
472   EXPECT_DEATH(strncat(to, from - 1, 2), LeftOOBReadMessage(1));
473   EXPECT_DEATH(strncat(to, from + from_size, 2), RightOOBReadMessage(0));
474 
475   memset(from, 'z', from_size);
476   memset(to, 'z', to_size);
477   to[0] = '\0';
478   // "from" is too short.
479   EXPECT_DEATH(strncat(to, from, from_size + 1), RightOOBReadMessage(0));
480   // "to" is too short to fit "from".
481   to[0] = 'z';
482   to[to_size - from_size + 1] = '\0';
483   EXPECT_DEATH(strncat(to, from, from_size - 1), RightOOBWriteMessage(0));
484   // "to" is just enough.
485   strncat(to, from, from_size - 2);
486 
487   free(to);
488   free(from);
489 }
490 
491 static std::string OverlapErrorMessage(const std::string &func) {
492   return func + "-param-overlap";
493 }
494 
495 TEST(AddressSanitizer, StrArgsOverlapTest) {
496   size_t size = Ident(100);
497   char *str = Ident((char*)malloc(size));
498 
499 // Do not check memcpy() on OS X 10.7 and later, where it actually aliases
500 // memmove().
501 #if !defined(__APPLE__) || !defined(MAC_OS_X_VERSION_10_7) || \
502     (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7)
503   // Check "memcpy". Use Ident() to avoid inlining.
504 #if PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE
505   memset(str, 'z', size);
506   Ident(memcpy)(str + 1, str + 11, 10);
507   Ident(memcpy)(str, str, 0);
508   EXPECT_DEATH(Ident(memcpy)(str, str + 14, 15), OverlapErrorMessage("memcpy"));
509   EXPECT_DEATH(Ident(memcpy)(str + 14, str, 15), OverlapErrorMessage("memcpy"));
510 #endif
511 #endif
512 
513   // We do not treat memcpy with to==from as a bug.
514   // See http://llvm.org/bugs/show_bug.cgi?id=11763.
515   // EXPECT_DEATH(Ident(memcpy)(str + 20, str + 20, 1),
516   //              OverlapErrorMessage("memcpy"));
517 
518   // Check "strcpy".
519   memset(str, 'z', size);
520   str[9] = '\0';
521   strcpy(str + 10, str);
522   EXPECT_DEATH(strcpy(str + 9, str), OverlapErrorMessage("strcpy"));
523   EXPECT_DEATH(strcpy(str, str + 4), OverlapErrorMessage("strcpy"));
524   strcpy(str, str + 5);
525 
526   // Check "strncpy".
527   memset(str, 'z', size);
528   strncpy(str, str + 10, 10);
529   EXPECT_DEATH(strncpy(str, str + 9, 10), OverlapErrorMessage("strncpy"));
530   EXPECT_DEATH(strncpy(str + 9, str, 10), OverlapErrorMessage("strncpy"));
531   str[10] = '\0';
532   strncpy(str + 11, str, 20);
533   EXPECT_DEATH(strncpy(str + 10, str, 20), OverlapErrorMessage("strncpy"));
534 
535   // Check "strcat".
536   memset(str, 'z', size);
537   str[10] = '\0';
538   str[20] = '\0';
539   strcat(str, str + 10);
540   EXPECT_DEATH(strcat(str, str + 11), OverlapErrorMessage("strcat"));
541   str[10] = '\0';
542   strcat(str + 11, str);
543   EXPECT_DEATH(strcat(str, str + 9), OverlapErrorMessage("strcat"));
544   EXPECT_DEATH(strcat(str + 9, str), OverlapErrorMessage("strcat"));
545   EXPECT_DEATH(strcat(str + 10, str), OverlapErrorMessage("strcat"));
546 
547   // Check "strncat".
548   memset(str, 'z', size);
549   str[10] = '\0';
550   strncat(str, str + 10, 10);  // from is empty
551   EXPECT_DEATH(strncat(str, str + 11, 10), OverlapErrorMessage("strncat"));
552   str[10] = '\0';
553   str[20] = '\0';
554   strncat(str + 5, str, 5);
555   str[10] = '\0';
556   EXPECT_DEATH(strncat(str + 5, str, 6), OverlapErrorMessage("strncat"));
557   EXPECT_DEATH(strncat(str, str + 9, 10), OverlapErrorMessage("strncat"));
558 
559   free(str);
560 }
561 
562 typedef void(*PointerToCallAtoi)(const char*);
563 
564 void RunAtoiOOBTest(PointerToCallAtoi Atoi) {
565   char *array = MallocAndMemsetString(10, '1');
566   // Invalid pointer to the string.
567   EXPECT_DEATH(Atoi(array + 11), RightOOBReadMessage(1));
568   EXPECT_DEATH(Atoi(array - 1), LeftOOBReadMessage(1));
569   // Die if a buffer doesn't have terminating NULL.
570   EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0));
571   // Make last symbol a terminating NULL
572   array[9] = '\0';
573   Atoi(array);
574   // Sometimes we need to detect overflow if no digits are found.
575   memset(array, ' ', 10);
576   EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0));
577   array[9] = '-';
578   EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0));
579   EXPECT_DEATH(Atoi(array + 9), RightOOBReadMessage(0));
580   free(array);
581 }
582 
583 #if !defined(_WIN32)  // FIXME: Fix and enable on Windows.
584 void CallAtoi(const char *nptr) {
585   Ident(atoi(nptr));
586 }
587 void CallAtol(const char *nptr) {
588   Ident(atol(nptr));
589 }
590 void CallAtoll(const char *nptr) {
591   Ident(atoll(nptr));
592 }
593 TEST(AddressSanitizer, AtoiAndFriendsOOBTest) {
594   RunAtoiOOBTest(&CallAtoi);
595   RunAtoiOOBTest(&CallAtol);
596   RunAtoiOOBTest(&CallAtoll);
597 }
598 #endif
599 
600 typedef void(*PointerToCallStrtol)(const char*, char**, int);
601 
602 void RunStrtolOOBTest(PointerToCallStrtol Strtol) {
603   char *array = MallocAndMemsetString(3);
604   array[0] = '1';
605   array[1] = '2';
606   array[2] = '3';
607   // Invalid pointer to the string.
608   EXPECT_DEATH(Strtol(array + 3, NULL, 0), RightOOBReadMessage(0));
609   EXPECT_DEATH(Strtol(array - 1, NULL, 0), LeftOOBReadMessage(1));
610   // Buffer overflow if there is no terminating null (depends on base).
611   EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));
612   array[2] = 'z';
613   EXPECT_DEATH(Strtol(array, NULL, 36), RightOOBReadMessage(0));
614   // Add terminating zero to get rid of overflow.
615   array[2] = '\0';
616   Strtol(array, NULL, 36);
617   // Sometimes we need to detect overflow if no digits are found.
618   array[0] = array[1] = array[2] = ' ';
619   EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));
620   array[2] = '+';
621   EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));
622   array[2] = '-';
623   EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));
624   free(array);
625 }
626 
627 #if !defined(_WIN32)  // FIXME: Fix and enable on Windows.
628 void CallStrtol(const char *nptr, char **endptr, int base) {
629   Ident(strtol(nptr, endptr, base));
630 }
631 void CallStrtoll(const char *nptr, char **endptr, int base) {
632   Ident(strtoll(nptr, endptr, base));
633 }
634 TEST(AddressSanitizer, StrtollOOBTest) {
635   RunStrtolOOBTest(&CallStrtoll);
636 }
637 TEST(AddressSanitizer, StrtolOOBTest) {
638   RunStrtolOOBTest(&CallStrtol);
639 }
640 #endif
641 
642 TEST(AddressSanitizer, StrtolOverflow) {
643   if (sizeof(long) == 4) {
644     // Check that errno gets set correctly on 32-bit strtol overflow.
645     long res;
646     errno = 0;
647     res = Ident(strtol("2147483647", NULL, 0));
648     EXPECT_EQ(errno, 0);
649     EXPECT_EQ(res, 2147483647);
650 
651     res = Ident(strtol("2147483648", NULL, 0));
652     EXPECT_EQ(errno, ERANGE);
653     EXPECT_EQ(res, 2147483647);
654 
655     errno = 0;
656     res = Ident(strtol("-2147483648", NULL, 0));
657     EXPECT_EQ(errno, 0);
658     EXPECT_EQ(res, -2147483648);
659 
660     res = Ident(strtol("-2147483649", NULL, 0));
661     EXPECT_EQ(errno, ERANGE);
662     EXPECT_EQ(res, -2147483648);
663   }
664 }
665