• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //=-- asan_str_test.cc ----------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is a part of AddressSanitizer, an address sanity checker.
11 //
12 //===----------------------------------------------------------------------===//
13 #include "asan_test_utils.h"
14 
15 // Used for string functions tests
16 static char global_string[] = "global";
17 static size_t global_string_length = 6;
18 
19 // Input to a test is a zero-terminated string str with given length
20 // Accesses to the bytes to the left and to the right of str
21 // are presumed to produce OOB errors
StrLenOOBTestTemplate(char * str,size_t length,bool is_global)22 void StrLenOOBTestTemplate(char *str, size_t length, bool is_global) {
23   // Normal strlen calls
24   EXPECT_EQ(strlen(str), length);
25   if (length > 0) {
26     EXPECT_EQ(length - 1, strlen(str + 1));
27     EXPECT_EQ(0U, strlen(str + length));
28   }
29   // Arg of strlen is not malloced, OOB access
30   if (!is_global) {
31     // We don't insert RedZones to the left of global variables
32     EXPECT_DEATH(Ident(strlen(str - 1)), LeftOOBReadMessage(1));
33     EXPECT_DEATH(Ident(strlen(str - 5)), LeftOOBReadMessage(5));
34   }
35   EXPECT_DEATH(Ident(strlen(str + length + 1)), RightOOBReadMessage(0));
36   // Overwrite terminator
37   str[length] = 'a';
38   // String is not zero-terminated, strlen will lead to OOB access
39   EXPECT_DEATH(Ident(strlen(str)), RightOOBReadMessage(0));
40   EXPECT_DEATH(Ident(strlen(str + length)), RightOOBReadMessage(0));
41   // Restore terminator
42   str[length] = 0;
43 }
TEST(AddressSanitizer,StrLenOOBTest)44 TEST(AddressSanitizer, StrLenOOBTest) {
45   // Check heap-allocated string
46   size_t length = Ident(10);
47   char *heap_string = Ident((char*)malloc(length + 1));
48   char stack_string[10 + 1];
49   break_optimization(&stack_string);
50   for (size_t i = 0; i < length; i++) {
51     heap_string[i] = 'a';
52     stack_string[i] = 'b';
53   }
54   heap_string[length] = 0;
55   stack_string[length] = 0;
56   StrLenOOBTestTemplate(heap_string, length, false);
57   // TODO(samsonov): Fix expected messages in StrLenOOBTestTemplate to
58   //      make test for stack_string work. Or move it to output tests.
59   // StrLenOOBTestTemplate(stack_string, length, false);
60   StrLenOOBTestTemplate(global_string, global_string_length, true);
61   free(heap_string);
62 }
63 
64 #ifndef __APPLE__
TEST(AddressSanitizer,StrNLenOOBTest)65 TEST(AddressSanitizer, StrNLenOOBTest) {
66   size_t size = Ident(123);
67   char *str = MallocAndMemsetString(size);
68   // Normal strnlen calls.
69   Ident(strnlen(str - 1, 0));
70   Ident(strnlen(str, size));
71   Ident(strnlen(str + size - 1, 1));
72   str[size - 1] = '\0';
73   Ident(strnlen(str, 2 * size));
74   // Argument points to not allocated memory.
75   EXPECT_DEATH(Ident(strnlen(str - 1, 1)), LeftOOBReadMessage(1));
76   EXPECT_DEATH(Ident(strnlen(str + size, 1)), RightOOBReadMessage(0));
77   // Overwrite the terminating '\0' and hit unallocated memory.
78   str[size - 1] = 'z';
79   EXPECT_DEATH(Ident(strnlen(str, size + 1)), RightOOBReadMessage(0));
80   free(str);
81 }
82 #endif
83 
TEST(AddressSanitizer,StrDupOOBTest)84 TEST(AddressSanitizer, StrDupOOBTest) {
85   size_t size = Ident(42);
86   char *str = MallocAndMemsetString(size);
87   char *new_str;
88   // Normal strdup calls.
89   str[size - 1] = '\0';
90   new_str = strdup(str);
91   free(new_str);
92   new_str = strdup(str + size - 1);
93   free(new_str);
94   // Argument points to not allocated memory.
95   EXPECT_DEATH(Ident(strdup(str - 1)), LeftOOBReadMessage(1));
96   EXPECT_DEATH(Ident(strdup(str + size)), RightOOBReadMessage(0));
97   // Overwrite the terminating '\0' and hit unallocated memory.
98   str[size - 1] = 'z';
99   EXPECT_DEATH(Ident(strdup(str)), RightOOBReadMessage(0));
100   free(str);
101 }
102 
TEST(AddressSanitizer,StrCpyOOBTest)103 TEST(AddressSanitizer, StrCpyOOBTest) {
104   size_t to_size = Ident(30);
105   size_t from_size = Ident(6);  // less than to_size
106   char *to = Ident((char*)malloc(to_size));
107   char *from = Ident((char*)malloc(from_size));
108   // Normal strcpy calls.
109   strcpy(from, "hello");
110   strcpy(to, from);
111   strcpy(to + to_size - from_size, from);
112   // Length of "from" is too small.
113   EXPECT_DEATH(Ident(strcpy(from, "hello2")), RightOOBWriteMessage(0));
114   // "to" or "from" points to not allocated memory.
115   EXPECT_DEATH(Ident(strcpy(to - 1, from)), LeftOOBWriteMessage(1));
116   EXPECT_DEATH(Ident(strcpy(to, from - 1)), LeftOOBReadMessage(1));
117   EXPECT_DEATH(Ident(strcpy(to, from + from_size)), RightOOBReadMessage(0));
118   EXPECT_DEATH(Ident(strcpy(to + to_size, from)), RightOOBWriteMessage(0));
119   // Overwrite the terminating '\0' character and hit unallocated memory.
120   from[from_size - 1] = '!';
121   EXPECT_DEATH(Ident(strcpy(to, from)), RightOOBReadMessage(0));
122   free(to);
123   free(from);
124 }
125 
TEST(AddressSanitizer,StrNCpyOOBTest)126 TEST(AddressSanitizer, StrNCpyOOBTest) {
127   size_t to_size = Ident(20);
128   size_t from_size = Ident(6);  // less than to_size
129   char *to = Ident((char*)malloc(to_size));
130   // From is a zero-terminated string "hello\0" of length 6
131   char *from = Ident((char*)malloc(from_size));
132   strcpy(from, "hello");
133   // copy 0 bytes
134   strncpy(to, from, 0);
135   strncpy(to - 1, from - 1, 0);
136   // normal strncpy calls
137   strncpy(to, from, from_size);
138   strncpy(to, from, to_size);
139   strncpy(to, from + from_size - 1, to_size);
140   strncpy(to + to_size - 1, from, 1);
141   // One of {to, from} points to not allocated memory
142   EXPECT_DEATH(Ident(strncpy(to, from - 1, from_size)),
143                LeftOOBReadMessage(1));
144   EXPECT_DEATH(Ident(strncpy(to - 1, from, from_size)),
145                LeftOOBWriteMessage(1));
146   EXPECT_DEATH(Ident(strncpy(to, from + from_size, 1)),
147                RightOOBReadMessage(0));
148   EXPECT_DEATH(Ident(strncpy(to + to_size, from, 1)),
149                RightOOBWriteMessage(0));
150   // Length of "to" is too small
151   EXPECT_DEATH(Ident(strncpy(to + to_size - from_size + 1, from, from_size)),
152                RightOOBWriteMessage(0));
153   EXPECT_DEATH(Ident(strncpy(to + 1, from, to_size)),
154                RightOOBWriteMessage(0));
155   // Overwrite terminator in from
156   from[from_size - 1] = '!';
157   // normal strncpy call
158   strncpy(to, from, from_size);
159   // Length of "from" is too small
160   EXPECT_DEATH(Ident(strncpy(to, from, to_size)),
161                RightOOBReadMessage(0));
162   free(to);
163   free(from);
164 }
165 
166 // Users may have different definitions of "strchr" and "index", so provide
167 // function pointer typedefs and overload RunStrChrTest implementation.
168 // We can't use macro for RunStrChrTest body here, as this macro would
169 // confuse EXPECT_DEATH gtest macro.
170 typedef char*(*PointerToStrChr1)(const char*, int);
171 typedef char*(*PointerToStrChr2)(char*, int);
172 
RunStrChrTest(PointerToStrChr1 StrChr)173 USED static void RunStrChrTest(PointerToStrChr1 StrChr) {
174   size_t size = Ident(100);
175   char *str = MallocAndMemsetString(size);
176   str[10] = 'q';
177   str[11] = '\0';
178   EXPECT_EQ(str, StrChr(str, 'z'));
179   EXPECT_EQ(str + 10, StrChr(str, 'q'));
180   EXPECT_EQ(NULL, StrChr(str, 'a'));
181   // StrChr argument points to not allocated memory.
182   EXPECT_DEATH(Ident(StrChr(str - 1, 'z')), LeftOOBReadMessage(1));
183   EXPECT_DEATH(Ident(StrChr(str + size, 'z')), RightOOBReadMessage(0));
184   // Overwrite the terminator and hit not allocated memory.
185   str[11] = 'z';
186   EXPECT_DEATH(Ident(StrChr(str, 'a')), RightOOBReadMessage(0));
187   free(str);
188 }
RunStrChrTest(PointerToStrChr2 StrChr)189 USED static void RunStrChrTest(PointerToStrChr2 StrChr) {
190   size_t size = Ident(100);
191   char *str = MallocAndMemsetString(size);
192   str[10] = 'q';
193   str[11] = '\0';
194   EXPECT_EQ(str, StrChr(str, 'z'));
195   EXPECT_EQ(str + 10, StrChr(str, 'q'));
196   EXPECT_EQ(NULL, StrChr(str, 'a'));
197   // StrChr argument points to not allocated memory.
198   EXPECT_DEATH(Ident(StrChr(str - 1, 'z')), LeftOOBReadMessage(1));
199   EXPECT_DEATH(Ident(StrChr(str + size, 'z')), RightOOBReadMessage(0));
200   // Overwrite the terminator and hit not allocated memory.
201   str[11] = 'z';
202   EXPECT_DEATH(Ident(StrChr(str, 'a')), RightOOBReadMessage(0));
203   free(str);
204 }
205 
TEST(AddressSanitizer,StrChrAndIndexOOBTest)206 TEST(AddressSanitizer, StrChrAndIndexOOBTest) {
207   RunStrChrTest(&strchr);
208   RunStrChrTest(&index);
209 }
210 
TEST(AddressSanitizer,StrCmpAndFriendsLogicTest)211 TEST(AddressSanitizer, StrCmpAndFriendsLogicTest) {
212   // strcmp
213   EXPECT_EQ(0, strcmp("", ""));
214   EXPECT_EQ(0, strcmp("abcd", "abcd"));
215   EXPECT_GT(0, strcmp("ab", "ac"));
216   EXPECT_GT(0, strcmp("abc", "abcd"));
217   EXPECT_LT(0, strcmp("acc", "abc"));
218   EXPECT_LT(0, strcmp("abcd", "abc"));
219 
220   // strncmp
221   EXPECT_EQ(0, strncmp("a", "b", 0));
222   EXPECT_EQ(0, strncmp("abcd", "abcd", 10));
223   EXPECT_EQ(0, strncmp("abcd", "abcef", 3));
224   EXPECT_GT(0, strncmp("abcde", "abcfa", 4));
225   EXPECT_GT(0, strncmp("a", "b", 5));
226   EXPECT_GT(0, strncmp("bc", "bcde", 4));
227   EXPECT_LT(0, strncmp("xyz", "xyy", 10));
228   EXPECT_LT(0, strncmp("baa", "aaa", 1));
229   EXPECT_LT(0, strncmp("zyx", "", 2));
230 
231   // strcasecmp
232   EXPECT_EQ(0, strcasecmp("", ""));
233   EXPECT_EQ(0, strcasecmp("zzz", "zzz"));
234   EXPECT_EQ(0, strcasecmp("abCD", "ABcd"));
235   EXPECT_GT(0, strcasecmp("aB", "Ac"));
236   EXPECT_GT(0, strcasecmp("ABC", "ABCd"));
237   EXPECT_LT(0, strcasecmp("acc", "abc"));
238   EXPECT_LT(0, strcasecmp("ABCd", "abc"));
239 
240   // strncasecmp
241   EXPECT_EQ(0, strncasecmp("a", "b", 0));
242   EXPECT_EQ(0, strncasecmp("abCD", "ABcd", 10));
243   EXPECT_EQ(0, strncasecmp("abCd", "ABcef", 3));
244   EXPECT_GT(0, strncasecmp("abcde", "ABCfa", 4));
245   EXPECT_GT(0, strncasecmp("a", "B", 5));
246   EXPECT_GT(0, strncasecmp("bc", "BCde", 4));
247   EXPECT_LT(0, strncasecmp("xyz", "xyy", 10));
248   EXPECT_LT(0, strncasecmp("Baa", "aaa", 1));
249   EXPECT_LT(0, strncasecmp("zyx", "", 2));
250 
251   // memcmp
252   EXPECT_EQ(0, memcmp("a", "b", 0));
253   EXPECT_EQ(0, memcmp("ab\0c", "ab\0c", 4));
254   EXPECT_GT(0, memcmp("\0ab", "\0ac", 3));
255   EXPECT_GT(0, memcmp("abb\0", "abba", 4));
256   EXPECT_LT(0, memcmp("ab\0cd", "ab\0c\0", 5));
257   EXPECT_LT(0, memcmp("zza", "zyx", 3));
258 }
259 
260 typedef int(*PointerToStrCmp)(const char*, const char*);
RunStrCmpTest(PointerToStrCmp StrCmp)261 void RunStrCmpTest(PointerToStrCmp StrCmp) {
262   size_t size = Ident(100);
263   int fill = 'o';
264   char *s1 = MallocAndMemsetString(size, fill);
265   char *s2 = MallocAndMemsetString(size, fill);
266   s1[size - 1] = '\0';
267   s2[size - 1] = '\0';
268   // Normal StrCmp calls
269   Ident(StrCmp(s1, s2));
270   Ident(StrCmp(s1, s2 + size - 1));
271   Ident(StrCmp(s1 + size - 1, s2 + size - 1));
272   s1[size - 1] = 'z';
273   s2[size - 1] = 'x';
274   Ident(StrCmp(s1, s2));
275   // One of arguments points to not allocated memory.
276   EXPECT_DEATH(Ident(StrCmp)(s1 - 1, s2), LeftOOBReadMessage(1));
277   EXPECT_DEATH(Ident(StrCmp)(s1, s2 - 1), LeftOOBReadMessage(1));
278   EXPECT_DEATH(Ident(StrCmp)(s1 + size, s2), RightOOBReadMessage(0));
279   EXPECT_DEATH(Ident(StrCmp)(s1, s2 + size), RightOOBReadMessage(0));
280   // Hit unallocated memory and die.
281   s1[size - 1] = fill;
282   EXPECT_DEATH(Ident(StrCmp)(s1, s1), RightOOBReadMessage(0));
283   EXPECT_DEATH(Ident(StrCmp)(s1 + size - 1, s2), RightOOBReadMessage(0));
284   free(s1);
285   free(s2);
286 }
287 
TEST(AddressSanitizer,StrCmpOOBTest)288 TEST(AddressSanitizer, StrCmpOOBTest) {
289   RunStrCmpTest(&strcmp);
290 }
291 
TEST(AddressSanitizer,StrCaseCmpOOBTest)292 TEST(AddressSanitizer, StrCaseCmpOOBTest) {
293   RunStrCmpTest(&strcasecmp);
294 }
295 
296 typedef int(*PointerToStrNCmp)(const char*, const char*, size_t);
RunStrNCmpTest(PointerToStrNCmp StrNCmp)297 void RunStrNCmpTest(PointerToStrNCmp StrNCmp) {
298   size_t size = Ident(100);
299   char *s1 = MallocAndMemsetString(size);
300   char *s2 = MallocAndMemsetString(size);
301   s1[size - 1] = '\0';
302   s2[size - 1] = '\0';
303   // Normal StrNCmp calls
304   Ident(StrNCmp(s1, s2, size + 2));
305   s1[size - 1] = 'z';
306   s2[size - 1] = 'x';
307   Ident(StrNCmp(s1 + size - 2, s2 + size - 2, size));
308   s2[size - 1] = 'z';
309   Ident(StrNCmp(s1 - 1, s2 - 1, 0));
310   Ident(StrNCmp(s1 + size - 1, s2 + size - 1, 1));
311   // One of arguments points to not allocated memory.
312   EXPECT_DEATH(Ident(StrNCmp)(s1 - 1, s2, 1), LeftOOBReadMessage(1));
313   EXPECT_DEATH(Ident(StrNCmp)(s1, s2 - 1, 1), LeftOOBReadMessage(1));
314   EXPECT_DEATH(Ident(StrNCmp)(s1 + size, s2, 1), RightOOBReadMessage(0));
315   EXPECT_DEATH(Ident(StrNCmp)(s1, s2 + size, 1), RightOOBReadMessage(0));
316   // Hit unallocated memory and die.
317   EXPECT_DEATH(Ident(StrNCmp)(s1 + 1, s2 + 1, size), RightOOBReadMessage(0));
318   EXPECT_DEATH(Ident(StrNCmp)(s1 + size - 1, s2, 2), RightOOBReadMessage(0));
319   free(s1);
320   free(s2);
321 }
322 
TEST(AddressSanitizer,StrNCmpOOBTest)323 TEST(AddressSanitizer, StrNCmpOOBTest) {
324   RunStrNCmpTest(&strncmp);
325 }
326 
TEST(AddressSanitizer,StrNCaseCmpOOBTest)327 TEST(AddressSanitizer, StrNCaseCmpOOBTest) {
328   RunStrNCmpTest(&strncasecmp);
329 }
TEST(AddressSanitizer,StrCatOOBTest)330 TEST(AddressSanitizer, StrCatOOBTest) {
331   // strcat() reads strlen(to) bytes from |to| before concatenating.
332   size_t to_size = Ident(100);
333   char *to = MallocAndMemsetString(to_size);
334   to[0] = '\0';
335   size_t from_size = Ident(20);
336   char *from = MallocAndMemsetString(from_size);
337   from[from_size - 1] = '\0';
338   // Normal strcat calls.
339   strcat(to, from);
340   strcat(to, from);
341   strcat(to + from_size, from + from_size - 2);
342   // Passing an invalid pointer is an error even when concatenating an empty
343   // string.
344   EXPECT_DEATH(strcat(to - 1, from + from_size - 1), LeftOOBAccessMessage(1));
345   // One of arguments points to not allocated memory.
346   EXPECT_DEATH(strcat(to - 1, from), LeftOOBAccessMessage(1));
347   EXPECT_DEATH(strcat(to, from - 1), LeftOOBReadMessage(1));
348   EXPECT_DEATH(strcat(to + to_size, from), RightOOBWriteMessage(0));
349   EXPECT_DEATH(strcat(to, from + from_size), RightOOBReadMessage(0));
350 
351   // "from" is not zero-terminated.
352   from[from_size - 1] = 'z';
353   EXPECT_DEATH(strcat(to, from), RightOOBReadMessage(0));
354   from[from_size - 1] = '\0';
355   // "to" is not zero-terminated.
356   memset(to, 'z', to_size);
357   EXPECT_DEATH(strcat(to, from), RightOOBWriteMessage(0));
358   // "to" is too short to fit "from".
359   to[to_size - from_size + 1] = '\0';
360   EXPECT_DEATH(strcat(to, from), RightOOBWriteMessage(0));
361   // length of "to" is just enough.
362   strcat(to, from + 1);
363 
364   free(to);
365   free(from);
366 }
367 
TEST(AddressSanitizer,StrNCatOOBTest)368 TEST(AddressSanitizer, StrNCatOOBTest) {
369   // strncat() reads strlen(to) bytes from |to| before concatenating.
370   size_t to_size = Ident(100);
371   char *to = MallocAndMemsetString(to_size);
372   to[0] = '\0';
373   size_t from_size = Ident(20);
374   char *from = MallocAndMemsetString(from_size);
375   // Normal strncat calls.
376   strncat(to, from, 0);
377   strncat(to, from, from_size);
378   from[from_size - 1] = '\0';
379   strncat(to, from, 2 * from_size);
380   // Catenating empty string with an invalid string is still an error.
381   EXPECT_DEATH(strncat(to - 1, from, 0), LeftOOBAccessMessage(1));
382   strncat(to, from + from_size - 1, 10);
383   // One of arguments points to not allocated memory.
384   EXPECT_DEATH(strncat(to - 1, from, 2), LeftOOBAccessMessage(1));
385   EXPECT_DEATH(strncat(to, from - 1, 2), LeftOOBReadMessage(1));
386   EXPECT_DEATH(strncat(to + to_size, from, 2), RightOOBWriteMessage(0));
387   EXPECT_DEATH(strncat(to, from + from_size, 2), RightOOBReadMessage(0));
388 
389   memset(from, 'z', from_size);
390   memset(to, 'z', to_size);
391   to[0] = '\0';
392   // "from" is too short.
393   EXPECT_DEATH(strncat(to, from, from_size + 1), RightOOBReadMessage(0));
394   // "to" is not zero-terminated.
395   EXPECT_DEATH(strncat(to + 1, from, 1), RightOOBWriteMessage(0));
396   // "to" is too short to fit "from".
397   to[0] = 'z';
398   to[to_size - from_size + 1] = '\0';
399   EXPECT_DEATH(strncat(to, from, from_size - 1), RightOOBWriteMessage(0));
400   // "to" is just enough.
401   strncat(to, from, from_size - 2);
402 
403   free(to);
404   free(from);
405 }
406 
OverlapErrorMessage(const string & func)407 static string OverlapErrorMessage(const string &func) {
408   return func + "-param-overlap";
409 }
410 
TEST(AddressSanitizer,StrArgsOverlapTest)411 TEST(AddressSanitizer, StrArgsOverlapTest) {
412   size_t size = Ident(100);
413   char *str = Ident((char*)malloc(size));
414 
415 // Do not check memcpy() on OS X 10.7 and later, where it actually aliases
416 // memmove().
417 #if !defined(__APPLE__) || !defined(MAC_OS_X_VERSION_10_7) || \
418     (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7)
419   // Check "memcpy". Use Ident() to avoid inlining.
420   memset(str, 'z', size);
421   Ident(memcpy)(str + 1, str + 11, 10);
422   Ident(memcpy)(str, str, 0);
423   EXPECT_DEATH(Ident(memcpy)(str, str + 14, 15), OverlapErrorMessage("memcpy"));
424   EXPECT_DEATH(Ident(memcpy)(str + 14, str, 15), OverlapErrorMessage("memcpy"));
425 #endif
426 
427   // We do not treat memcpy with to==from as a bug.
428   // See http://llvm.org/bugs/show_bug.cgi?id=11763.
429   // EXPECT_DEATH(Ident(memcpy)(str + 20, str + 20, 1),
430   //              OverlapErrorMessage("memcpy"));
431 
432   // Check "strcpy".
433   memset(str, 'z', size);
434   str[9] = '\0';
435   strcpy(str + 10, str);
436   EXPECT_DEATH(strcpy(str + 9, str), OverlapErrorMessage("strcpy"));
437   EXPECT_DEATH(strcpy(str, str + 4), OverlapErrorMessage("strcpy"));
438   strcpy(str, str + 5);
439 
440   // Check "strncpy".
441   memset(str, 'z', size);
442   strncpy(str, str + 10, 10);
443   EXPECT_DEATH(strncpy(str, str + 9, 10), OverlapErrorMessage("strncpy"));
444   EXPECT_DEATH(strncpy(str + 9, str, 10), OverlapErrorMessage("strncpy"));
445   str[10] = '\0';
446   strncpy(str + 11, str, 20);
447   EXPECT_DEATH(strncpy(str + 10, str, 20), OverlapErrorMessage("strncpy"));
448 
449   // Check "strcat".
450   memset(str, 'z', size);
451   str[10] = '\0';
452   str[20] = '\0';
453   strcat(str, str + 10);
454   EXPECT_DEATH(strcat(str, str + 11), OverlapErrorMessage("strcat"));
455   str[10] = '\0';
456   strcat(str + 11, str);
457   EXPECT_DEATH(strcat(str, str + 9), OverlapErrorMessage("strcat"));
458   EXPECT_DEATH(strcat(str + 9, str), OverlapErrorMessage("strcat"));
459   EXPECT_DEATH(strcat(str + 10, str), OverlapErrorMessage("strcat"));
460 
461   // Check "strncat".
462   memset(str, 'z', size);
463   str[10] = '\0';
464   strncat(str, str + 10, 10);  // from is empty
465   EXPECT_DEATH(strncat(str, str + 11, 10), OverlapErrorMessage("strncat"));
466   str[10] = '\0';
467   str[20] = '\0';
468   strncat(str + 5, str, 5);
469   str[10] = '\0';
470   EXPECT_DEATH(strncat(str + 5, str, 6), OverlapErrorMessage("strncat"));
471   EXPECT_DEATH(strncat(str, str + 9, 10), OverlapErrorMessage("strncat"));
472 
473   free(str);
474 }
475 
CallAtoi(const char * nptr)476 void CallAtoi(const char *nptr) {
477   Ident(atoi(nptr));
478 }
CallAtol(const char * nptr)479 void CallAtol(const char *nptr) {
480   Ident(atol(nptr));
481 }
CallAtoll(const char * nptr)482 void CallAtoll(const char *nptr) {
483   Ident(atoll(nptr));
484 }
485 typedef void(*PointerToCallAtoi)(const char*);
486 
RunAtoiOOBTest(PointerToCallAtoi Atoi)487 void RunAtoiOOBTest(PointerToCallAtoi Atoi) {
488   char *array = MallocAndMemsetString(10, '1');
489   // Invalid pointer to the string.
490   EXPECT_DEATH(Atoi(array + 11), RightOOBReadMessage(1));
491   EXPECT_DEATH(Atoi(array - 1), LeftOOBReadMessage(1));
492   // Die if a buffer doesn't have terminating NULL.
493   EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0));
494   // Make last symbol a terminating NULL or other non-digit.
495   array[9] = '\0';
496   Atoi(array);
497   array[9] = 'a';
498   Atoi(array);
499   Atoi(array + 9);
500   // Sometimes we need to detect overflow if no digits are found.
501   memset(array, ' ', 10);
502   EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0));
503   array[9] = '-';
504   EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0));
505   EXPECT_DEATH(Atoi(array + 9), RightOOBReadMessage(0));
506   array[8] = '-';
507   Atoi(array);
508   free(array);
509 }
510 
TEST(AddressSanitizer,AtoiAndFriendsOOBTest)511 TEST(AddressSanitizer, AtoiAndFriendsOOBTest) {
512   RunAtoiOOBTest(&CallAtoi);
513   RunAtoiOOBTest(&CallAtol);
514   RunAtoiOOBTest(&CallAtoll);
515 }
516 
CallStrtol(const char * nptr,char ** endptr,int base)517 void CallStrtol(const char *nptr, char **endptr, int base) {
518   Ident(strtol(nptr, endptr, base));
519 }
CallStrtoll(const char * nptr,char ** endptr,int base)520 void CallStrtoll(const char *nptr, char **endptr, int base) {
521   Ident(strtoll(nptr, endptr, base));
522 }
523 typedef void(*PointerToCallStrtol)(const char*, char**, int);
524 
RunStrtolOOBTest(PointerToCallStrtol Strtol)525 void RunStrtolOOBTest(PointerToCallStrtol Strtol) {
526   char *array = MallocAndMemsetString(3);
527   char *endptr = NULL;
528   array[0] = '1';
529   array[1] = '2';
530   array[2] = '3';
531   // Invalid pointer to the string.
532   EXPECT_DEATH(Strtol(array + 3, NULL, 0), RightOOBReadMessage(0));
533   EXPECT_DEATH(Strtol(array - 1, NULL, 0), LeftOOBReadMessage(1));
534   // Buffer overflow if there is no terminating null (depends on base).
535   Strtol(array, &endptr, 3);
536   EXPECT_EQ(array + 2, endptr);
537   EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));
538   array[2] = 'z';
539   Strtol(array, &endptr, 35);
540   EXPECT_EQ(array + 2, endptr);
541   EXPECT_DEATH(Strtol(array, NULL, 36), RightOOBReadMessage(0));
542   // Add terminating zero to get rid of overflow.
543   array[2] = '\0';
544   Strtol(array, NULL, 36);
545   // Don't check for overflow if base is invalid.
546   Strtol(array - 1, NULL, -1);
547   Strtol(array + 3, NULL, 1);
548   // Sometimes we need to detect overflow if no digits are found.
549   array[0] = array[1] = array[2] = ' ';
550   EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));
551   array[2] = '+';
552   EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));
553   array[2] = '-';
554   EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));
555   array[1] = '+';
556   Strtol(array, NULL, 0);
557   array[1] = array[2] = 'z';
558   Strtol(array, &endptr, 0);
559   EXPECT_EQ(array, endptr);
560   Strtol(array + 2, NULL, 0);
561   EXPECT_EQ(array, endptr);
562   free(array);
563 }
564 
TEST(AddressSanitizer,StrtollOOBTest)565 TEST(AddressSanitizer, StrtollOOBTest) {
566   RunStrtolOOBTest(&CallStrtoll);
567 }
TEST(AddressSanitizer,StrtolOOBTest)568 TEST(AddressSanitizer, StrtolOOBTest) {
569   RunStrtolOOBTest(&CallStrtol);
570 }
571 
572 
573