debug: make __read_chk a cancellation point (bug 29274)
[platform/upstream/glibc.git] / debug / tst-fortify.c
1 /* Copyright (C) 2004-2022 Free Software Foundation, Inc.
2    Copyright The GNU Toolchain Authors.
3    This file is part of the GNU C Library.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <https://www.gnu.org/licenses/>.  */
18
19 /* This file tests gets.  Force it to be declared.  */
20 #include <features.h>
21 #undef __GLIBC_USE_DEPRECATED_GETS
22 #define __GLIBC_USE_DEPRECATED_GETS 1
23
24 #include <assert.h>
25 #include <fcntl.h>
26 #include <locale.h>
27 #include <obstack.h>
28 #include <setjmp.h>
29 #include <signal.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <wchar.h>
35 #include <sys/poll.h>
36 #include <sys/select.h>
37 #include <sys/socket.h>
38 #include <sys/un.h>
39
40 #ifndef _GNU_SOURCE
41 # define MEMPCPY memcpy
42 # define WMEMPCPY wmemcpy
43 # define MEMPCPY_RET(x) 0
44 # define WMEMPCPY_RET(x) 0
45 #else
46 # define MEMPCPY mempcpy
47 # define WMEMPCPY wmempcpy
48 # define MEMPCPY_RET(x) __builtin_strlen (x)
49 # define WMEMPCPY_RET(x) wcslen (x)
50 #endif
51
52 #define obstack_chunk_alloc malloc
53 #define obstack_chunk_free free
54
55 char *temp_filename;
56 static void do_prepare (void);
57 static int do_test (void);
58 #define PREPARE(argc, argv) do_prepare ()
59 #define TEST_FUNCTION do_test ()
60 #include "../test-skeleton.c"
61
62 static void
63 do_prepare (void)
64 {
65   int temp_fd = create_temp_file ("tst-chk1.", &temp_filename);
66   if (temp_fd == -1)
67     {
68       printf ("cannot create temporary file: %m\n");
69       exit (1);
70     }
71
72   const char *strs = "abcdefgh\nABCDEFGHI\nabcdefghij\nABCDEFGHIJ";
73   if ((size_t) write (temp_fd, strs, strlen (strs)) != strlen (strs))
74     {
75       puts ("could not write test strings into file");
76       unlink (temp_filename);
77       exit (1);
78     }
79 }
80
81 volatile int chk_fail_ok;
82 volatile int ret;
83 jmp_buf chk_fail_buf;
84
85 static void
86 handler (int sig)
87 {
88   if (chk_fail_ok)
89     {
90       chk_fail_ok = 0;
91       longjmp (chk_fail_buf, 1);
92     }
93   else
94     _exit (127);
95 }
96
97 #if __USE_FORTIFY_LEVEL == 3
98 volatile size_t buf_size = 10;
99 #else
100 char buf[10];
101 wchar_t wbuf[10];
102 #define buf_size sizeof (buf)
103 #endif
104
105 volatile size_t l0;
106 volatile char *p;
107 volatile wchar_t *wp;
108 const char *str1 = "JIHGFEDCBA";
109 const char *str2 = "F";
110 const char *str3 = "%s%n%s%n";
111 const char *str4 = "Hello, ";
112 const char *str5 = "World!\n";
113 const wchar_t *wstr1 = L"JIHGFEDCBA";
114 const wchar_t *wstr2 = L"F";
115 const wchar_t *wstr3 = L"%s%n%s%n";
116 const wchar_t *wstr4 = L"Hello, ";
117 const wchar_t *wstr5 = L"World!\n";
118 char buf2[10] = "%s";
119 int num1 = 67;
120 int num2 = 987654;
121
122 #define FAIL() \
123   do { printf ("Failure on line %d\n", __LINE__); ret = 1; } while (0)
124 #define CHK_FAIL_START \
125   chk_fail_ok = 1;                              \
126   if (! setjmp (chk_fail_buf))                  \
127     {
128 #define CHK_FAIL_END \
129       chk_fail_ok = 0;                          \
130       FAIL ();                                  \
131     }
132 #if __USE_FORTIFY_LEVEL >= 2 && (!defined __cplusplus || defined __va_arg_pack)
133 # define CHK_FAIL2_START CHK_FAIL_START
134 # define CHK_FAIL2_END CHK_FAIL_END
135 #else
136 # define CHK_FAIL2_START
137 # define CHK_FAIL2_END
138 #endif
139
140 static int
141 do_test (void)
142 {
143 #if __USE_FORTIFY_LEVEL == 3
144   char *buf = (char *) malloc (buf_size);
145   wchar_t *wbuf = (wchar_t *) malloc (buf_size * sizeof (wchar_t));
146 #endif
147   set_fortify_handler (handler);
148
149   struct A { char buf1[9]; char buf2[1]; } a;
150   struct wA { wchar_t buf1[9]; wchar_t buf2[1]; } wa;
151
152   printf ("Test checking routines at fortify level %d\n",
153 #ifdef __USE_FORTIFY_LEVEL
154           (int) __USE_FORTIFY_LEVEL
155 #else
156           0
157 #endif
158           );
159
160 #if defined __USE_FORTIFY_LEVEL && !defined __fortify_function
161   printf ("Test skipped");
162   if (l0 == 0)
163     return 0;
164 #endif
165
166   /* These ops can be done without runtime checking of object size.  */
167   memcpy (buf, "abcdefghij", 10);
168   memmove (buf + 1, buf, 9);
169   if (memcmp (buf, "aabcdefghi", 10))
170     FAIL ();
171
172   memcpy (buf, "abcdefghij", 10);
173   bcopy (buf, buf + 1, 9);
174   if (memcmp (buf, "aabcdefghi", 10))
175     FAIL ();
176
177   if (MEMPCPY (buf + 5, "abcde", 5) != buf + 5 + MEMPCPY_RET ("abcde")
178       || memcmp (buf, "aabcdabcde", 10))
179     FAIL ();
180
181   memset (buf + 8, 'j', 2);
182   if (memcmp (buf, "aabcdabcjj", 10))
183     FAIL ();
184
185   bzero (buf + 8, 2);
186   if (memcmp (buf, "aabcdabc\0\0", 10))
187     FAIL ();
188
189   explicit_bzero (buf + 6, 4);
190   if (memcmp (buf, "aabcda\0\0\0\0", 10))
191     FAIL ();
192
193   strcpy (buf + 4, "EDCBA");
194   if (memcmp (buf, "aabcEDCBA", 10))
195     FAIL ();
196
197   if (stpcpy (buf + 8, "F") != buf + 9 || memcmp (buf, "aabcEDCBF", 10))
198     FAIL ();
199
200   strncpy (buf + 6, "X", 4);
201   if (memcmp (buf, "aabcEDX\0\0", 10))
202     FAIL ();
203
204   if (sprintf (buf + 7, "%s", "67") != 2 || memcmp (buf, "aabcEDX67", 10))
205     FAIL ();
206
207   if (snprintf (buf + 7, 3, "%s", "987654") != 6
208       || memcmp (buf, "aabcEDX98", 10))
209     FAIL ();
210
211   /* These ops need runtime checking, but shouldn't __chk_fail.  */
212   memcpy (buf, "abcdefghij", l0 + 10);
213   memmove (buf + 1, buf, l0 + 9);
214   if (memcmp (buf, "aabcdefghi", 10))
215     FAIL ();
216
217   memcpy (buf, "abcdefghij", l0 + 10);
218   bcopy (buf, buf + 1, l0 + 9);
219   if (memcmp (buf, "aabcdefghi", 10))
220     FAIL ();
221
222   if (MEMPCPY (buf + 5, "abcde", l0 + 5) != buf + 5 + MEMPCPY_RET ("abcde")
223       || memcmp (buf, "aabcdabcde", 10))
224     FAIL ();
225
226   memset (buf + 8, 'j', l0 + 2);
227   if (memcmp (buf, "aabcdabcjj", 10))
228     FAIL ();
229
230   bzero (buf + 8, l0 + 2);
231   if (memcmp (buf, "aabcdabc\0\0", 10))
232     FAIL ();
233
234   explicit_bzero (buf + 6, l0 + 4);
235   if (memcmp (buf, "aabcda\0\0\0\0", 10))
236     FAIL ();
237
238   strcpy (buf + 4, str1 + 5);
239   if (memcmp (buf, "aabcEDCBA", 10))
240     FAIL ();
241
242   if (stpcpy (buf + 8, str2) != buf + 9 || memcmp (buf, "aabcEDCBF", 10))
243     FAIL ();
244
245   strncpy (buf + 6, "X", l0 + 4);
246   if (memcmp (buf, "aabcEDX\0\0", 10))
247     FAIL ();
248
249   if (stpncpy (buf + 5, "cd", l0 + 5) != buf + 7
250       || memcmp (buf, "aabcEcd\0\0", 10))
251     FAIL ();
252
253   if (sprintf (buf + 7, "%d", num1) != 2 || memcmp (buf, "aabcEcd67", 10))
254     FAIL ();
255
256   if (snprintf (buf + 7, 3, "%d", num2) != 6 || memcmp (buf, "aabcEcd98", 10))
257     FAIL ();
258
259   buf[l0 + 8] = '\0';
260   strcat (buf, "A");
261   if (memcmp (buf, "aabcEcd9A", 10))
262     FAIL ();
263
264   buf[l0 + 7] = '\0';
265   strncat (buf, "ZYXWV", l0 + 2);
266   if (memcmp (buf, "aabcEcdZY", 10))
267     FAIL ();
268
269   /* The following tests are supposed to succeed at all fortify
270      levels, even though they overflow a.buf1 into a.buf2.  */
271   memcpy (a.buf1, "abcdefghij", l0 + 10);
272   memmove (a.buf1 + 1, a.buf1, l0 + 9);
273   if (memcmp (a.buf1, "aabcdefghi", 10))
274     FAIL ();
275
276   memcpy (a.buf1, "abcdefghij", l0 + 10);
277   bcopy (a.buf1, a.buf1 + 1, l0 + 9);
278   if (memcmp (a.buf1, "aabcdefghi", 10))
279     FAIL ();
280
281   if (MEMPCPY (a.buf1 + 5, "abcde", l0 + 5)
282       != a.buf1 + 5 + MEMPCPY_RET ("abcde")
283       || memcmp (a.buf1, "aabcdabcde", 10))
284     FAIL ();
285
286   memset (a.buf1 + 8, 'j', l0 + 2);
287   if (memcmp (a.buf1, "aabcdabcjj", 10))
288     FAIL ();
289
290   bzero (a.buf1 + 8, l0 + 2);
291   if (memcmp (a.buf1, "aabcdabc\0\0", 10))
292     FAIL ();
293
294   explicit_bzero (a.buf1 + 6, l0 + 4);
295   if (memcmp (a.buf1, "aabcda\0\0\0\0", 10))
296     FAIL ();
297
298 #if __USE_FORTIFY_LEVEL < 2
299   /* The following tests are supposed to crash with -D_FORTIFY_SOURCE=2
300      and sufficient GCC support, as the string operations overflow
301      from a.buf1 into a.buf2.  */
302   strcpy (a.buf1 + 4, str1 + 5);
303   if (memcmp (a.buf1, "aabcEDCBA", 10))
304     FAIL ();
305
306   if (stpcpy (a.buf1 + 8, str2) != a.buf1 + 9
307       || memcmp (a.buf1, "aabcEDCBF", 10))
308     FAIL ();
309
310   strncpy (a.buf1 + 6, "X", l0 + 4);
311   if (memcmp (a.buf1, "aabcEDX\0\0", 10))
312     FAIL ();
313
314   if (sprintf (a.buf1 + 7, "%d", num1) != 2
315       || memcmp (a.buf1, "aabcEDX67", 10))
316     FAIL ();
317
318   if (snprintf (a.buf1 + 7, 3, "%d", num2) != 6
319       || memcmp (a.buf1, "aabcEDX98", 10))
320     FAIL ();
321
322   a.buf1[l0 + 8] = '\0';
323   strcat (a.buf1, "A");
324   if (memcmp (a.buf1, "aabcEDX9A", 10))
325     FAIL ();
326
327   a.buf1[l0 + 7] = '\0';
328   strncat (a.buf1, "ZYXWV", l0 + 2);
329   if (memcmp (a.buf1, "aabcEDXZY", 10))
330     FAIL ();
331
332 #endif
333
334 #if __USE_FORTIFY_LEVEL >= 1
335   /* Now check if all buffer overflows are caught at runtime.
336      N.B. All tests involving a length parameter need to be done
337      twice: once with the length a compile-time constant, once without.  */
338
339   CHK_FAIL_START
340   memcpy (buf + 1, "abcdefghij", 10);
341   CHK_FAIL_END
342
343   CHK_FAIL_START
344   memcpy (buf + 1, "abcdefghij", l0 + 10);
345   CHK_FAIL_END
346
347   CHK_FAIL_START
348   memmove (buf + 2, buf + 1, 9);
349   CHK_FAIL_END
350
351   CHK_FAIL_START
352   memmove (buf + 2, buf + 1, l0 + 9);
353   CHK_FAIL_END
354
355   CHK_FAIL_START
356   bcopy (buf + 1, buf + 2, 9);
357   CHK_FAIL_END
358
359   CHK_FAIL_START
360   bcopy (buf + 1, buf + 2, l0 + 9);
361   CHK_FAIL_END
362
363 #ifdef _GNU_SOURCE
364   CHK_FAIL_START
365   p = (char *) mempcpy (buf + 6, "abcde", 5);
366   CHK_FAIL_END
367
368   CHK_FAIL_START
369   p = (char *) mempcpy (buf + 6, "abcde", l0 + 5);
370   CHK_FAIL_END
371 #endif
372
373   CHK_FAIL_START
374   memset (buf + 9, 'j', 2);
375   CHK_FAIL_END
376
377   CHK_FAIL_START
378   memset (buf + 9, 'j', l0 + 2);
379   CHK_FAIL_END
380
381   CHK_FAIL_START
382   bzero (buf + 9, 2);
383   CHK_FAIL_END
384
385   CHK_FAIL_START
386   bzero (buf + 9, l0 + 2);
387   CHK_FAIL_END
388
389   CHK_FAIL_START
390   explicit_bzero (buf + 9, 2);
391   CHK_FAIL_END
392
393   CHK_FAIL_START
394   explicit_bzero (buf + 9, l0 + 2);
395   CHK_FAIL_END
396
397   CHK_FAIL_START
398   strcpy (buf + 5, str1 + 5);
399   CHK_FAIL_END
400
401   CHK_FAIL_START
402   p = stpcpy (buf + 9, str2);
403   CHK_FAIL_END
404
405   CHK_FAIL_START
406   strncpy (buf + 7, "X", 4);
407   CHK_FAIL_END
408
409   CHK_FAIL_START
410   strncpy (buf + 7, "X", l0 + 4);
411   CHK_FAIL_END
412
413   CHK_FAIL_START
414   stpncpy (buf + 6, "cd", 5);
415   CHK_FAIL_END
416
417   CHK_FAIL_START
418   stpncpy (buf + 6, "cd", l0 + 5);
419   CHK_FAIL_END
420
421 # if !defined __cplusplus || defined __va_arg_pack
422   CHK_FAIL_START
423   sprintf (buf + 8, "%d", num1);
424   CHK_FAIL_END
425
426   CHK_FAIL_START
427   snprintf (buf + 8, 3, "%d", num2);
428   CHK_FAIL_END
429
430   CHK_FAIL_START
431   snprintf (buf + 8, l0 + 3, "%d", num2);
432   CHK_FAIL_END
433
434   CHK_FAIL_START
435   swprintf (wbuf + 8, 3, L"%d", num1);
436   CHK_FAIL_END
437
438   CHK_FAIL_START
439   swprintf (wbuf + 8, l0 + 3, L"%d", num1);
440   CHK_FAIL_END
441 # endif
442
443   memcpy (buf, str1 + 2, 9);
444   CHK_FAIL_START
445   strcat (buf, "AB");
446   CHK_FAIL_END
447
448   memcpy (buf, str1 + 3, 8);
449   CHK_FAIL_START
450   strncat (buf, "ZYXWV", 3);
451   CHK_FAIL_END
452
453   memcpy (buf, str1 + 3, 8);
454   CHK_FAIL_START
455   strncat (buf, "ZYXWV", l0 + 3);
456   CHK_FAIL_END
457
458   CHK_FAIL_START
459   memcpy (a.buf1 + 1, "abcdefghij", 10);
460   CHK_FAIL_END
461
462   CHK_FAIL_START
463   memcpy (a.buf1 + 1, "abcdefghij", l0 + 10);
464   CHK_FAIL_END
465
466   CHK_FAIL_START
467   memmove (a.buf1 + 2, a.buf1 + 1, 9);
468   CHK_FAIL_END
469
470   CHK_FAIL_START
471   memmove (a.buf1 + 2, a.buf1 + 1, l0 + 9);
472   CHK_FAIL_END
473
474   CHK_FAIL_START
475   bcopy (a.buf1 + 1, a.buf1 + 2, 9);
476   CHK_FAIL_END
477
478   CHK_FAIL_START
479   bcopy (a.buf1 + 1, a.buf1 + 2, l0 + 9);
480   CHK_FAIL_END
481
482 #ifdef _GNU_SOURCE
483   CHK_FAIL_START
484   p = (char *) mempcpy (a.buf1 + 6, "abcde", 5);
485   CHK_FAIL_END
486
487   CHK_FAIL_START
488   p = (char *) mempcpy (a.buf1 + 6, "abcde", l0 + 5);
489   CHK_FAIL_END
490 #endif
491
492   CHK_FAIL_START
493   memset (a.buf1 + 9, 'j', 2);
494   CHK_FAIL_END
495
496   CHK_FAIL_START
497   memset (a.buf1 + 9, 'j', l0 + 2);
498   CHK_FAIL_END
499
500   CHK_FAIL_START
501   bzero (a.buf1 + 9, 2);
502   CHK_FAIL_END
503
504   CHK_FAIL_START
505   bzero (a.buf1 + 9, l0 + 2);
506   CHK_FAIL_END
507
508   CHK_FAIL_START
509   explicit_bzero (a.buf1 + 9, 2);
510   CHK_FAIL_END
511
512   CHK_FAIL_START
513   explicit_bzero (a.buf1 + 9, l0 + 2);
514   CHK_FAIL_END
515
516 # if __USE_FORTIFY_LEVEL >= 2
517 #  define O 0
518 # else
519 #  define O 1
520 # endif
521
522   CHK_FAIL_START
523   strcpy (a.buf1 + (O + 4), str1 + 5);
524   CHK_FAIL_END
525
526   CHK_FAIL_START
527   p = stpcpy (a.buf1 + (O + 8), str2);
528   CHK_FAIL_END
529
530   CHK_FAIL_START
531   strncpy (a.buf1 + (O + 6), "X", 4);
532   CHK_FAIL_END
533
534   CHK_FAIL_START
535   strncpy (a.buf1 + (O + 6), "X", l0 + 4);
536   CHK_FAIL_END
537
538 # if !defined __cplusplus || defined __va_arg_pack
539   CHK_FAIL_START
540   sprintf (a.buf1 + (O + 7), "%d", num1);
541   CHK_FAIL_END
542
543   CHK_FAIL_START
544   snprintf (a.buf1 + (O + 7), 3, "%d", num2);
545   CHK_FAIL_END
546
547   CHK_FAIL_START
548   snprintf (a.buf1 + (O + 7), l0 + 3, "%d", num2);
549   CHK_FAIL_END
550 # endif
551
552   memcpy (a.buf1, str1 + (3 - O), 8 + O);
553   CHK_FAIL_START
554   strcat (a.buf1, "AB");
555   CHK_FAIL_END
556
557   memcpy (a.buf1, str1 + (4 - O), 7 + O);
558   CHK_FAIL_START
559   strncat (a.buf1, "ZYXWV", l0 + 3);
560   CHK_FAIL_END
561 #endif
562
563
564   /* These ops can be done without runtime checking of object size.  */
565   wmemcpy (wbuf, L"abcdefghij", 10);
566   wmemmove (wbuf + 1, wbuf, 9);
567   if (wmemcmp (wbuf, L"aabcdefghi", 10))
568     FAIL ();
569
570   if (WMEMPCPY (wbuf + 5, L"abcde", 5) != wbuf + 5 + WMEMPCPY_RET (L"abcde")
571       || wmemcmp (wbuf, L"aabcdabcde", 10))
572     FAIL ();
573
574   wmemset (wbuf + 8, L'j', 2);
575   if (wmemcmp (wbuf, L"aabcdabcjj", 10))
576     FAIL ();
577
578   wcscpy (wbuf + 4, L"EDCBA");
579   if (wmemcmp (wbuf, L"aabcEDCBA", 10))
580     FAIL ();
581
582   if (wcpcpy (wbuf + 8, L"F") != wbuf + 9 || wmemcmp (wbuf, L"aabcEDCBF", 10))
583     FAIL ();
584
585   wcsncpy (wbuf + 6, L"X", 4);
586   if (wmemcmp (wbuf, L"aabcEDX\0\0", 10))
587     FAIL ();
588
589   if (swprintf (wbuf + 7, 3, L"%ls", L"987654") >= 0
590       || wmemcmp (wbuf, L"aabcEDX98", 10))
591     FAIL ();
592
593   if (swprintf (wbuf + 7, 3, L"64") != 2
594       || wmemcmp (wbuf, L"aabcEDX64", 10))
595     FAIL ();
596
597   /* These ops need runtime checking, but shouldn't __chk_fail.  */
598   wmemcpy (wbuf, L"abcdefghij", l0 + 10);
599   wmemmove (wbuf + 1, wbuf, l0 + 9);
600   if (wmemcmp (wbuf, L"aabcdefghi", 10))
601     FAIL ();
602
603   if (WMEMPCPY (wbuf + 5, L"abcde", l0 + 5)
604       != wbuf + 5 + WMEMPCPY_RET (L"abcde")
605       || wmemcmp (wbuf, L"aabcdabcde", 10))
606     FAIL ();
607
608   wmemset (wbuf + 8, L'j', l0 + 2);
609   if (wmemcmp (wbuf, L"aabcdabcjj", 10))
610     FAIL ();
611
612   wcscpy (wbuf + 4, wstr1 + 5);
613   if (wmemcmp (wbuf, L"aabcEDCBA", 10))
614     FAIL ();
615
616   if (wcpcpy (wbuf + 8, wstr2) != wbuf + 9 || wmemcmp (wbuf, L"aabcEDCBF", 10))
617     FAIL ();
618
619   wcsncpy (wbuf + 6, L"X", l0 + 4);
620   if (wmemcmp (wbuf, L"aabcEDX\0\0", 10))
621     FAIL ();
622
623   if (wcpncpy (wbuf + 5, L"cd", l0 + 5) != wbuf + 7
624       || wmemcmp (wbuf, L"aabcEcd\0\0", 10))
625     FAIL ();
626
627   if (swprintf (wbuf + 7, 3, L"%d", num2) >= 0
628       || wmemcmp (wbuf, L"aabcEcd98", 10))
629     FAIL ();
630
631   wbuf[l0 + 8] = L'\0';
632   wcscat (wbuf, L"A");
633   if (wmemcmp (wbuf, L"aabcEcd9A", 10))
634     FAIL ();
635
636   wbuf[l0 + 7] = L'\0';
637   wcsncat (wbuf, L"ZYXWV", l0 + 2);
638   if (wmemcmp (wbuf, L"aabcEcdZY", 10))
639     FAIL ();
640
641   wmemcpy (wa.buf1, L"abcdefghij", l0 + 10);
642   wmemmove (wa.buf1 + 1, wa.buf1, l0 + 9);
643   if (wmemcmp (wa.buf1, L"aabcdefghi", 10))
644     FAIL ();
645
646   if (WMEMPCPY (wa.buf1 + 5, L"abcde", l0 + 5)
647       != wa.buf1 + 5 + WMEMPCPY_RET (L"abcde")
648       || wmemcmp (wa.buf1, L"aabcdabcde", 10))
649     FAIL ();
650
651   wmemset (wa.buf1 + 8, L'j', l0 + 2);
652   if (wmemcmp (wa.buf1, L"aabcdabcjj", 10))
653     FAIL ();
654
655 #if __USE_FORTIFY_LEVEL < 2
656   /* The following tests are supposed to crash with -D_FORTIFY_SOURCE=2
657      and sufficient GCC support, as the string operations overflow
658      from a.buf1 into a.buf2.  */
659   wcscpy (wa.buf1 + 4, wstr1 + 5);
660   if (wmemcmp (wa.buf1, L"aabcEDCBA", 10))
661     FAIL ();
662
663   if (wcpcpy (wa.buf1 + 8, wstr2) != wa.buf1 + 9
664       || wmemcmp (wa.buf1, L"aabcEDCBF", 10))
665     FAIL ();
666
667   wcsncpy (wa.buf1 + 6, L"X", l0 + 4);
668   if (wmemcmp (wa.buf1, L"aabcEDX\0\0", 10))
669     FAIL ();
670
671   if (swprintf (wa.buf1 + 7, 3, L"%d", num2) >= 0
672       || wmemcmp (wa.buf1, L"aabcEDX98", 10))
673     FAIL ();
674
675   wa.buf1[l0 + 8] = L'\0';
676   wcscat (wa.buf1, L"A");
677   if (wmemcmp (wa.buf1, L"aabcEDX9A", 10))
678     FAIL ();
679
680   wa.buf1[l0 + 7] = L'\0';
681   wcsncat (wa.buf1, L"ZYXWV", l0 + 2);
682   if (wmemcmp (wa.buf1, L"aabcEDXZY", 10))
683     FAIL ();
684
685 #endif
686
687 #if __USE_FORTIFY_LEVEL >= 1
688   /* Now check if all buffer overflows are caught at runtime.
689      N.B. All tests involving a length parameter need to be done
690      twice: once with the length a compile-time constant, once without.  */
691
692   CHK_FAIL_START
693   wmemcpy (wbuf + 1, L"abcdefghij", 10);
694   CHK_FAIL_END
695
696   CHK_FAIL_START
697   wmemcpy (wbuf + 1, L"abcdefghij", l0 + 10);
698   CHK_FAIL_END
699
700   CHK_FAIL_START
701   wmemcpy (wbuf + 9, L"abcdefghij", 10);
702   CHK_FAIL_END
703
704   CHK_FAIL_START
705   wmemcpy (wbuf + 9, L"abcdefghij", l0 + 10);
706   CHK_FAIL_END
707
708   CHK_FAIL_START
709   wmemmove (wbuf + 2, wbuf + 1, 9);
710   CHK_FAIL_END
711
712   CHK_FAIL_START
713   wmemmove (wbuf + 2, wbuf + 1, l0 + 9);
714   CHK_FAIL_END
715
716 #ifdef _GNU_SOURCE
717   CHK_FAIL_START
718   wp = wmempcpy (wbuf + 6, L"abcde", 5);
719   CHK_FAIL_END
720
721   CHK_FAIL_START
722   wp = wmempcpy (wbuf + 6, L"abcde", l0 + 5);
723   CHK_FAIL_END
724 #endif
725
726   CHK_FAIL_START
727   wmemset (wbuf + 9, L'j', 2);
728   CHK_FAIL_END
729
730   CHK_FAIL_START
731   wmemset (wbuf + 9, L'j', l0 + 2);
732   CHK_FAIL_END
733
734   CHK_FAIL_START
735   wcscpy (wbuf + 5, wstr1 + 5);
736   CHK_FAIL_END
737
738   CHK_FAIL_START
739   wp = wcpcpy (wbuf + 9, wstr2);
740   CHK_FAIL_END
741
742   CHK_FAIL_START
743   wcsncpy (wbuf + 7, L"X", 4);
744   CHK_FAIL_END
745
746   CHK_FAIL_START
747   wcsncpy (wbuf + 7, L"X", l0 + 4);
748   CHK_FAIL_END
749
750   CHK_FAIL_START
751   wcsncpy (wbuf + 9, L"XABCDEFGH", 8);
752   CHK_FAIL_END
753
754   CHK_FAIL_START
755   wcpncpy (wbuf + 9, L"XABCDEFGH", 8);
756   CHK_FAIL_END
757
758   CHK_FAIL_START
759   wcpncpy (wbuf + 6, L"cd", 5);
760   CHK_FAIL_END
761
762   CHK_FAIL_START
763   wcpncpy (wbuf + 6, L"cd", l0 + 5);
764   CHK_FAIL_END
765
766   wmemcpy (wbuf, wstr1 + 2, 9);
767   CHK_FAIL_START
768   wcscat (wbuf, L"AB");
769   CHK_FAIL_END
770
771   wmemcpy (wbuf, wstr1 + 3, 8);
772   CHK_FAIL_START
773   wcsncat (wbuf, L"ZYXWV", l0 + 3);
774   CHK_FAIL_END
775
776   CHK_FAIL_START
777   wmemcpy (wa.buf1 + 1, L"abcdefghij", 10);
778   CHK_FAIL_END
779
780   CHK_FAIL_START
781   wmemcpy (wa.buf1 + 1, L"abcdefghij", l0 + 10);
782   CHK_FAIL_END
783
784   CHK_FAIL_START
785   wmemmove (wa.buf1 + 2, wa.buf1 + 1, 9);
786   CHK_FAIL_END
787
788   CHK_FAIL_START
789   wmemmove (wa.buf1 + 2, wa.buf1 + 1, l0 + 9);
790   CHK_FAIL_END
791
792 #ifdef _GNU_SOURCE
793   CHK_FAIL_START
794   wp = wmempcpy (wa.buf1 + 6, L"abcde", 5);
795   CHK_FAIL_END
796
797   CHK_FAIL_START
798   wp = wmempcpy (wa.buf1 + 6, L"abcde", l0 + 5);
799   CHK_FAIL_END
800 #endif
801
802   CHK_FAIL_START
803   wmemset (wa.buf1 + 9, L'j', 2);
804   CHK_FAIL_END
805
806   CHK_FAIL_START
807   wmemset (wa.buf1 + 9, L'j', l0 + 2);
808   CHK_FAIL_END
809
810 #if __USE_FORTIFY_LEVEL >= 2
811 # define O 0
812 #else
813 # define O 1
814 #endif
815
816   CHK_FAIL_START
817   wcscpy (wa.buf1 + (O + 4), wstr1 + 5);
818   CHK_FAIL_END
819
820   CHK_FAIL_START
821   wp = wcpcpy (wa.buf1 + (O + 8), wstr2);
822   CHK_FAIL_END
823
824   CHK_FAIL_START
825   wcsncpy (wa.buf1 + (O + 6), L"X", 4);
826   CHK_FAIL_END
827
828   CHK_FAIL_START
829   wcsncpy (wa.buf1 + (O + 6), L"X", l0 + 4);
830   CHK_FAIL_END
831
832   wmemcpy (wa.buf1, wstr1 + (3 - O), 8 + O);
833   CHK_FAIL_START
834   wcscat (wa.buf1, L"AB");
835   CHK_FAIL_END
836
837   wmemcpy (wa.buf1, wstr1 + (4 - O), 7 + O);
838   CHK_FAIL_START
839   wcsncat (wa.buf1, L"ZYXWV", l0 + 3);
840   CHK_FAIL_END
841 #endif
842
843
844   /* Now checks for %n protection.  */
845
846   /* Constant literals passed directly are always ok
847      (even with warnings about possible bugs from GCC).  */
848   int n1, n2;
849   if (sprintf (buf, "%s%n%s%n", str2, &n1, str2, &n2) != 2
850       || n1 != 1 || n2 != 2)
851     FAIL ();
852
853   /* In this case the format string is not known at compile time,
854      but resides in read-only memory, so is ok.  */
855   if (snprintf (buf, 4, str3, str2, &n1, str2, &n2) != 2
856       || n1 != 1 || n2 != 2)
857     FAIL ();
858
859   strcpy (buf2 + 2, "%n%s%n");
860   /* When the format string is writable and contains %n,
861      with -D_FORTIFY_SOURCE=2 it causes __chk_fail.  */
862   CHK_FAIL2_START
863   if (sprintf (buf, buf2, str2, &n1, str2, &n1) != 2)
864     FAIL ();
865   CHK_FAIL2_END
866
867   CHK_FAIL2_START
868   if (snprintf (buf, 3, buf2, str2, &n1, str2, &n1) != 2)
869     FAIL ();
870   CHK_FAIL2_END
871
872   /* But if there is no %n, even writable format string
873      should work.  */
874   buf2[6] = '\0';
875   if (sprintf (buf, buf2 + 4, str2) != 1)
876     FAIL ();
877
878   /* Constant literals passed directly are always ok
879      (even with warnings about possible bugs from GCC).  */
880   if (printf ("%s%n%s%n", str4, &n1, str5, &n2) != 14
881       || n1 != 7 || n2 != 14)
882     FAIL ();
883
884   /* In this case the format string is not known at compile time,
885      but resides in read-only memory, so is ok.  */
886   if (printf (str3, str4, &n1, str5, &n2) != 14
887       || n1 != 7 || n2 != 14)
888     FAIL ();
889
890   strcpy (buf2 + 2, "%n%s%n");
891   /* When the format string is writable and contains %n,
892      with -D_FORTIFY_SOURCE=2 it causes __chk_fail.  */
893   CHK_FAIL2_START
894   if (printf (buf2, str4, &n1, str5, &n1) != 14)
895     FAIL ();
896   CHK_FAIL2_END
897
898   /* But if there is no %n, even writable format string
899      should work.  */
900   buf2[6] = '\0';
901   if (printf (buf2 + 4, str5) != 7)
902     FAIL ();
903
904   FILE *fp = stdout;
905
906   /* Constant literals passed directly are always ok
907      (even with warnings about possible bugs from GCC).  */
908   if (fprintf (fp, "%s%n%s%n", str4, &n1, str5, &n2) != 14
909       || n1 != 7 || n2 != 14)
910     FAIL ();
911
912   /* In this case the format string is not known at compile time,
913      but resides in read-only memory, so is ok.  */
914   if (fprintf (fp, str3, str4, &n1, str5, &n2) != 14
915       || n1 != 7 || n2 != 14)
916     FAIL ();
917
918   strcpy (buf2 + 2, "%n%s%n");
919   /* When the format string is writable and contains %n,
920      with -D_FORTIFY_SOURCE=2 it causes __chk_fail.  */
921   CHK_FAIL2_START
922   if (fprintf (fp, buf2, str4, &n1, str5, &n1) != 14)
923     FAIL ();
924   CHK_FAIL2_END
925
926   /* But if there is no %n, even writable format string
927      should work.  */
928   buf2[6] = '\0';
929   if (fprintf (fp, buf2 + 4, str5) != 7)
930     FAIL ();
931
932 #ifdef _GNU_SOURCE
933   char *my_ptr = NULL;
934   strcpy (buf2 + 2, "%n%s%n");
935   /* When the format string is writable and contains %n,
936      with -D_FORTIFY_SOURCE=2 it causes __chk_fail.  */
937   CHK_FAIL2_START
938   if (asprintf (&my_ptr, buf2, str4, &n1, str5, &n1) != 14)
939     FAIL ();
940   else
941     free (my_ptr);
942   CHK_FAIL2_END
943
944   struct obstack obs;
945   obstack_init (&obs);
946   CHK_FAIL2_START
947   if (obstack_printf (&obs, buf2, str4, &n1, str5, &n1) != 14)
948     FAIL ();
949   CHK_FAIL2_END
950   obstack_free (&obs, NULL);
951
952   my_ptr = NULL;
953   if (asprintf (&my_ptr, "%s%n%s%n", str4, &n1, str5, &n1) != 14)
954     FAIL ();
955   else
956     free (my_ptr);
957
958   obstack_init (&obs);
959   if (obstack_printf (&obs, "%s%n%s%n", str4, &n1, str5, &n1) != 14)
960     FAIL ();
961   obstack_free (&obs, NULL);
962 #endif
963
964   if (freopen (temp_filename, "r", stdin) == NULL)
965     {
966       puts ("could not open temporary file");
967       exit (1);
968     }
969
970   if (gets (buf) != buf || memcmp (buf, "abcdefgh", 9))
971     FAIL ();
972   if (gets (buf) != buf || memcmp (buf, "ABCDEFGHI", 10))
973     FAIL ();
974
975 #if __USE_FORTIFY_LEVEL >= 1
976   CHK_FAIL_START
977   if (gets (buf) != buf)
978     FAIL ();
979   CHK_FAIL_END
980 #endif
981
982   rewind (stdin);
983
984   if (fgets (buf, buf_size, stdin) != buf
985       || memcmp (buf, "abcdefgh\n", 10))
986     FAIL ();
987   if (fgets (buf, buf_size, stdin) != buf || memcmp (buf, "ABCDEFGHI", 10))
988     FAIL ();
989
990   rewind (stdin);
991
992   if (fgets (buf, l0 + buf_size, stdin) != buf
993       || memcmp (buf, "abcdefgh\n", 10))
994     FAIL ();
995
996 #if __USE_FORTIFY_LEVEL >= 1
997   CHK_FAIL_START
998   if (fgets (buf, buf_size + 1, stdin) != buf)
999     FAIL ();
1000   CHK_FAIL_END
1001
1002   CHK_FAIL_START
1003   if (fgets (buf, l0 + buf_size + 1, stdin) != buf)
1004     FAIL ();
1005   CHK_FAIL_END
1006 #endif
1007
1008   rewind (stdin);
1009
1010 #ifdef _GNU_SOURCE
1011   if (fgets_unlocked (buf, buf_size, stdin) != buf
1012       || memcmp (buf, "abcdefgh\n", 10))
1013     FAIL ();
1014   if (fgets_unlocked (buf, buf_size, stdin) != buf
1015       || memcmp (buf, "ABCDEFGHI", 10))
1016     FAIL ();
1017
1018   rewind (stdin);
1019
1020   if (fgets_unlocked (buf, l0 + buf_size, stdin) != buf
1021       || memcmp (buf, "abcdefgh\n", 10))
1022     FAIL ();
1023
1024 #if __USE_FORTIFY_LEVEL >= 1
1025   CHK_FAIL_START
1026   if (fgets_unlocked (buf, buf_size + 1, stdin) != buf)
1027     FAIL ();
1028   CHK_FAIL_END
1029
1030   CHK_FAIL_START
1031   if (fgets_unlocked (buf, l0 + buf_size + 1, stdin) != buf)
1032     FAIL ();
1033   CHK_FAIL_END
1034 #endif
1035
1036   rewind (stdin);
1037 #endif
1038
1039   if (fread (buf, 1, buf_size, stdin) != buf_size
1040       || memcmp (buf, "abcdefgh\nA", 10))
1041     FAIL ();
1042   if (fread (buf, buf_size, 1, stdin) != 1
1043       || memcmp (buf, "BCDEFGHI\na", 10))
1044     FAIL ();
1045
1046   rewind (stdin);
1047
1048   if (fread (buf, l0 + 1, buf_size, stdin) != buf_size
1049       || memcmp (buf, "abcdefgh\nA", 10))
1050     FAIL ();
1051   if (fread (buf, buf_size, l0 + 1, stdin) != 1
1052       || memcmp (buf, "BCDEFGHI\na", 10))
1053     FAIL ();
1054
1055 #if __USE_FORTIFY_LEVEL >= 1
1056   CHK_FAIL_START
1057   if (fread (buf, 1, buf_size + 1, stdin) != buf_size + 1)
1058     FAIL ();
1059   CHK_FAIL_END
1060
1061   CHK_FAIL_START
1062   if (fread (buf, buf_size + 1, l0 + 1, stdin) != 1)
1063     FAIL ();
1064   CHK_FAIL_END
1065 #endif
1066
1067   rewind (stdin);
1068
1069   if (fread_unlocked (buf, 1, buf_size, stdin) != buf_size
1070       || memcmp (buf, "abcdefgh\nA", 10))
1071     FAIL ();
1072   if (fread_unlocked (buf, buf_size, 1, stdin) != 1
1073       || memcmp (buf, "BCDEFGHI\na", 10))
1074     FAIL ();
1075
1076   rewind (stdin);
1077
1078   if (fread_unlocked (buf, 1, 4, stdin) != 4
1079       || memcmp (buf, "abcdFGHI\na", 10))
1080     FAIL ();
1081   if (fread_unlocked (buf, 4, 1, stdin) != 1
1082       || memcmp (buf, "efghFGHI\na", 10))
1083     FAIL ();
1084
1085   rewind (stdin);
1086
1087   if (fread_unlocked (buf, l0 + 1, buf_size, stdin) != buf_size
1088       || memcmp (buf, "abcdefgh\nA", 10))
1089     FAIL ();
1090   if (fread_unlocked (buf, buf_size, l0 + 1, stdin) != 1
1091       || memcmp (buf, "BCDEFGHI\na", 10))
1092     FAIL ();
1093
1094 #if __USE_FORTIFY_LEVEL >= 1
1095   CHK_FAIL_START
1096   if (fread_unlocked (buf, 1, buf_size + 1, stdin) != buf_size + 1)
1097     FAIL ();
1098   CHK_FAIL_END
1099
1100   CHK_FAIL_START
1101   if (fread_unlocked (buf, buf_size + 1, l0 + 1, stdin) != 1)
1102     FAIL ();
1103   CHK_FAIL_END
1104 #endif
1105
1106   lseek (fileno (stdin), 0, SEEK_SET);
1107
1108   if (read (fileno (stdin), buf, buf_size - 1) != buf_size - 1
1109       || memcmp (buf, "abcdefgh\n", 9))
1110     FAIL ();
1111   if (read (fileno (stdin), buf, buf_size - 1) != buf_size - 1
1112       || memcmp (buf, "ABCDEFGHI", 9))
1113     FAIL ();
1114
1115   lseek (fileno (stdin), 0, SEEK_SET);
1116
1117   if (read (fileno (stdin), buf, l0 + buf_size - 1) != buf_size - 1
1118       || memcmp (buf, "abcdefgh\n", 9))
1119     FAIL ();
1120
1121 #if __USE_FORTIFY_LEVEL >= 1
1122   CHK_FAIL_START
1123   if (read (fileno (stdin), buf, buf_size + 1) != buf_size + 1)
1124     FAIL ();
1125   CHK_FAIL_END
1126
1127   CHK_FAIL_START
1128   if (read (fileno (stdin), buf, l0 + buf_size + 1) != buf_size + 1)
1129     FAIL ();
1130   CHK_FAIL_END
1131 #endif
1132
1133   if (pread (fileno (stdin), buf, buf_size - 1, buf_size - 2)
1134       != buf_size - 1
1135       || memcmp (buf, "\nABCDEFGH", 9))
1136     FAIL ();
1137   if (pread (fileno (stdin), buf, buf_size - 1, 0) != buf_size - 1
1138       || memcmp (buf, "abcdefgh\n", 9))
1139     FAIL ();
1140   if (pread (fileno (stdin), buf, l0 + buf_size - 1, buf_size - 3)
1141       != buf_size - 1
1142       || memcmp (buf, "h\nABCDEFG", 9))
1143     FAIL ();
1144
1145 #if __USE_FORTIFY_LEVEL >= 1
1146   CHK_FAIL_START
1147   if (pread (fileno (stdin), buf, buf_size + 1, 2 * buf_size)
1148       != buf_size + 1)
1149     FAIL ();
1150   CHK_FAIL_END
1151
1152   CHK_FAIL_START
1153   if (pread (fileno (stdin), buf, l0 + buf_size + 1, 2 * buf_size)
1154       != buf_size + 1)
1155     FAIL ();
1156   CHK_FAIL_END
1157 #endif
1158
1159   if (pread64 (fileno (stdin), buf, buf_size - 1, buf_size - 2)
1160       != buf_size - 1
1161       || memcmp (buf, "\nABCDEFGH", 9))
1162     FAIL ();
1163   if (pread64 (fileno (stdin), buf, buf_size - 1, 0) != buf_size - 1
1164       || memcmp (buf, "abcdefgh\n", 9))
1165     FAIL ();
1166   if (pread64 (fileno (stdin), buf, l0 + buf_size - 1, buf_size - 3)
1167       != buf_size - 1
1168       || memcmp (buf, "h\nABCDEFG", 9))
1169     FAIL ();
1170
1171 #if __USE_FORTIFY_LEVEL >= 1
1172   CHK_FAIL_START
1173   if (pread64 (fileno (stdin), buf, buf_size + 1, 2 * buf_size)
1174       != buf_size + 1)
1175     FAIL ();
1176   CHK_FAIL_END
1177
1178   CHK_FAIL_START
1179   if (pread64 (fileno (stdin), buf, l0 + buf_size + 1, 2 * buf_size)
1180       != buf_size + 1)
1181     FAIL ();
1182   CHK_FAIL_END
1183 #endif
1184
1185   if (freopen (temp_filename, "r", stdin) == NULL)
1186     {
1187       puts ("could not open temporary file");
1188       exit (1);
1189     }
1190
1191   if (fseek (stdin, 9 + 10 + 11, SEEK_SET))
1192     {
1193       puts ("could not seek in test file");
1194       exit (1);
1195     }
1196
1197 #if __USE_FORTIFY_LEVEL >= 1
1198   CHK_FAIL_START
1199   if (gets (buf) != buf)
1200     FAIL ();
1201   CHK_FAIL_END
1202 #endif
1203
1204   /* Check whether missing N$ formats are detected.  */
1205   CHK_FAIL2_START
1206   printf ("%3$d\n", 1, 2, 3, 4);
1207   CHK_FAIL2_END
1208
1209   CHK_FAIL2_START
1210   fprintf (stdout, "%3$d\n", 1, 2, 3, 4);
1211   CHK_FAIL2_END
1212
1213   CHK_FAIL2_START
1214   sprintf (buf, "%3$d\n", 1, 2, 3, 4);
1215   CHK_FAIL2_END
1216
1217   CHK_FAIL2_START
1218   snprintf (buf, buf_size, "%3$d\n", 1, 2, 3, 4);
1219   CHK_FAIL2_END
1220
1221   int sp[2];
1222   if (socketpair (PF_UNIX, SOCK_STREAM, 0, sp))
1223     FAIL ();
1224   else
1225     {
1226       const char *sendstr = "abcdefgh\nABCDEFGH\n0123456789\n";
1227       if ((size_t) send (sp[0], sendstr, strlen (sendstr), 0)
1228           != strlen (sendstr))
1229         FAIL ();
1230
1231       char recvbuf[12];
1232       if (recv (sp[1], recvbuf, sizeof recvbuf, MSG_PEEK)
1233           != sizeof recvbuf
1234           || memcmp (recvbuf, sendstr, sizeof recvbuf) != 0)
1235         FAIL ();
1236
1237       if (recv (sp[1], recvbuf + 6, l0 + sizeof recvbuf - 7, MSG_PEEK)
1238           != sizeof recvbuf - 7
1239           || memcmp (recvbuf + 6, sendstr, sizeof recvbuf - 7) != 0)
1240         FAIL ();
1241
1242 #if __USE_FORTIFY_LEVEL >= 1
1243       CHK_FAIL_START
1244       if (recv (sp[1], recvbuf + 1, sizeof recvbuf, MSG_PEEK)
1245           != sizeof recvbuf)
1246         FAIL ();
1247       CHK_FAIL_END
1248
1249       CHK_FAIL_START
1250       if (recv (sp[1], recvbuf + 4, l0 + sizeof recvbuf - 3, MSG_PEEK)
1251           != sizeof recvbuf - 3)
1252         FAIL ();
1253       CHK_FAIL_END
1254 #endif
1255
1256       socklen_t sl;
1257       struct sockaddr_un sa_un;
1258
1259       sl = sizeof (sa_un);
1260       if (recvfrom (sp[1], recvbuf, sizeof recvbuf, MSG_PEEK,
1261                     (struct sockaddr *) &sa_un, &sl)
1262           != sizeof recvbuf
1263           || memcmp (recvbuf, sendstr, sizeof recvbuf) != 0)
1264         FAIL ();
1265
1266       sl = sizeof (sa_un);
1267       if (recvfrom (sp[1], recvbuf + 6, l0 + sizeof recvbuf - 7, MSG_PEEK,
1268                     (struct sockaddr *) &sa_un, &sl) != sizeof recvbuf - 7
1269           || memcmp (recvbuf + 6, sendstr, sizeof recvbuf - 7) != 0)
1270         FAIL ();
1271
1272 #if __USE_FORTIFY_LEVEL >= 1
1273       CHK_FAIL_START
1274       sl = sizeof (sa_un);
1275       if (recvfrom (sp[1], recvbuf + 1, sizeof recvbuf, MSG_PEEK,
1276                     (struct sockaddr *) &sa_un, &sl) != sizeof recvbuf)
1277         FAIL ();
1278       CHK_FAIL_END
1279
1280       CHK_FAIL_START
1281       sl = sizeof (sa_un);
1282       if (recvfrom (sp[1], recvbuf + 4, l0 + sizeof recvbuf - 3, MSG_PEEK,
1283                     (struct sockaddr *) &sa_un, &sl) != sizeof recvbuf - 3)
1284         FAIL ();
1285       CHK_FAIL_END
1286 #endif
1287
1288       close (sp[0]);
1289       close (sp[1]);
1290     }
1291
1292   char fname[] = "/tmp/tst-chk1-dir-XXXXXX\0foo";
1293   char *enddir = strchr (fname, '\0');
1294   if (mkdtemp (fname) == NULL)
1295     {
1296       printf ("mkdtemp failed: %m\n");
1297       return 1;
1298     }
1299   *enddir = '/';
1300   if (symlink ("bar", fname) != 0)
1301     FAIL ();
1302
1303   char readlinkbuf[4];
1304   if (readlink (fname, readlinkbuf, 4) != 3
1305       || memcmp (readlinkbuf, "bar", 3) != 0)
1306     FAIL ();
1307   if (readlink (fname, readlinkbuf + 1, l0 + 3) != 3
1308       || memcmp (readlinkbuf, "bbar", 4) != 0)
1309     FAIL ();
1310
1311 #if __USE_FORTIFY_LEVEL >= 1
1312   CHK_FAIL_START
1313   if (readlink (fname, readlinkbuf + 2, l0 + 3) != 3)
1314     FAIL ();
1315   CHK_FAIL_END
1316
1317   CHK_FAIL_START
1318   if (readlink (fname, readlinkbuf + 3, 4) != 3)
1319     FAIL ();
1320   CHK_FAIL_END
1321 #endif
1322
1323   int tmpfd = open ("/tmp", O_RDONLY | O_DIRECTORY);
1324   if (tmpfd < 0)
1325     FAIL ();
1326
1327   if (readlinkat (tmpfd, fname + sizeof ("/tmp/") - 1, readlinkbuf, 4) != 3
1328       || memcmp (readlinkbuf, "bar", 3) != 0)
1329     FAIL ();
1330   if (readlinkat (tmpfd, fname + sizeof ("/tmp/") - 1, readlinkbuf + 1,
1331                   l0 + 3) != 3
1332       || memcmp (readlinkbuf, "bbar", 4) != 0)
1333     FAIL ();
1334
1335 #if __USE_FORTIFY_LEVEL >= 1
1336   CHK_FAIL_START
1337   if (readlinkat (tmpfd, fname + sizeof ("/tmp/") - 1, readlinkbuf + 2,
1338                   l0 + 3) != 3)
1339     FAIL ();
1340   CHK_FAIL_END
1341
1342   CHK_FAIL_START
1343   if (readlinkat (tmpfd, fname + sizeof ("/tmp/") - 1, readlinkbuf + 3,
1344                   4) != 3)
1345     FAIL ();
1346   CHK_FAIL_END
1347 #endif
1348
1349   close (tmpfd);
1350
1351   char *cwd1 = getcwd (NULL, 0);
1352   if (cwd1 == NULL)
1353     FAIL ();
1354
1355   char *cwd2 = getcwd (NULL, 250);
1356   if (cwd2 == NULL)
1357     FAIL ();
1358
1359   if (cwd1 && cwd2)
1360     {
1361       if (strcmp (cwd1, cwd2) != 0)
1362         FAIL ();
1363
1364       *enddir = '\0';
1365       if (chdir (fname))
1366         FAIL ();
1367
1368       char *cwd3 = getcwd (NULL, 0);
1369       if (cwd3 == NULL)
1370         FAIL ();
1371       if (strcmp (fname, cwd3) != 0)
1372         printf ("getcwd after chdir is '%s' != '%s',"
1373                 "get{c,}wd tests skipped\n", cwd3, fname);
1374       else
1375         {
1376           char getcwdbuf[sizeof fname - 3];
1377
1378           char *cwd4 = getcwd (getcwdbuf, sizeof getcwdbuf);
1379           if (cwd4 != getcwdbuf
1380               || strcmp (getcwdbuf, fname) != 0)
1381             FAIL ();
1382
1383           cwd4 = getcwd (getcwdbuf + 1, l0 + sizeof getcwdbuf - 1);
1384           if (cwd4 != getcwdbuf + 1
1385               || getcwdbuf[0] != fname[0]
1386               || strcmp (getcwdbuf + 1, fname) != 0)
1387             FAIL ();
1388
1389 #if __USE_FORTIFY_LEVEL >= 1
1390           CHK_FAIL_START
1391           if (getcwd (getcwdbuf + 2, l0 + sizeof getcwdbuf)
1392               != getcwdbuf + 2)
1393             FAIL ();
1394           CHK_FAIL_END
1395
1396           CHK_FAIL_START
1397           if (getcwd (getcwdbuf + 2, sizeof getcwdbuf)
1398               != getcwdbuf + 2)
1399             FAIL ();
1400           CHK_FAIL_END
1401 #endif
1402
1403           if (getwd (getcwdbuf) != getcwdbuf
1404               || strcmp (getcwdbuf, fname) != 0)
1405             FAIL ();
1406
1407           if (getwd (getcwdbuf + 1) != getcwdbuf + 1
1408               || strcmp (getcwdbuf + 1, fname) != 0)
1409             FAIL ();
1410
1411 #if __USE_FORTIFY_LEVEL >= 1
1412           CHK_FAIL_START
1413           if (getwd (getcwdbuf + 2) != getcwdbuf + 2)
1414             FAIL ();
1415           CHK_FAIL_END
1416 #endif
1417         }
1418
1419       if (chdir (cwd1) != 0)
1420         FAIL ();
1421       free (cwd3);
1422     }
1423
1424   free (cwd1);
1425   free (cwd2);
1426   *enddir = '/';
1427   if (unlink (fname) != 0)
1428     FAIL ();
1429
1430   *enddir = '\0';
1431   if (rmdir (fname) != 0)
1432     FAIL ();
1433
1434
1435 #if PATH_MAX > 0
1436   char largebuf[PATH_MAX];
1437   char *realres = realpath (".", largebuf);
1438   if (realres != largebuf)
1439     FAIL ();
1440
1441 # if __USE_FORTIFY_LEVEL >= 1
1442   CHK_FAIL_START
1443   char realbuf[1];
1444   realres = realpath (".", realbuf);
1445   if (realres != realbuf)
1446     FAIL ();
1447   CHK_FAIL_END
1448 # endif
1449 #endif
1450
1451   if (setlocale (LC_ALL, "de_DE.UTF-8") != NULL)
1452     {
1453       assert (MB_CUR_MAX <= 10);
1454
1455       /* First a simple test.  */
1456       char enough[10];
1457       if (wctomb (enough, L'A') != 1)
1458         FAIL ();
1459
1460 #if __USE_FORTIFY_LEVEL >= 1
1461       /* We know the wchar_t encoding is ISO 10646.  So pick a
1462          character which has a multibyte representation which does not
1463          fit.  */
1464       CHK_FAIL_START
1465       char smallbuf[2];
1466       if (wctomb (smallbuf, L'\x100') != 2)
1467         FAIL ();
1468       CHK_FAIL_END
1469 #endif
1470
1471       mbstate_t s;
1472       memset (&s, '\0', sizeof (s));
1473       if (wcrtomb (enough, L'D', &s) != 1 || enough[0] != 'D')
1474         FAIL ();
1475
1476 #if __USE_FORTIFY_LEVEL >= 1
1477       /* We know the wchar_t encoding is ISO 10646.  So pick a
1478          character which has a multibyte representation which does not
1479          fit.  */
1480       CHK_FAIL_START
1481       char smallbuf[1];
1482       if (wcrtomb (smallbuf, L'\x100', &s) != 2)
1483         FAIL ();
1484       CHK_FAIL_END
1485
1486       /* Same input with a large enough buffer and we're good.  */
1487       char bigenoughbuf[2];
1488       if (wcrtomb (bigenoughbuf, L'\x100', &s) != 2)
1489         FAIL ();
1490 #endif
1491
1492       wchar_t wenough[10];
1493       memset (&s, '\0', sizeof (s));
1494       const char *cp = "A";
1495       if (mbsrtowcs (wenough, &cp, 10, &s) != 1
1496           || wcscmp (wenough, L"A") != 0)
1497         FAIL ();
1498
1499       cp = "BC";
1500       if (mbsrtowcs (wenough, &cp, l0 + 10, &s) != 2
1501           || wcscmp (wenough, L"BC") != 0)
1502         FAIL ();
1503
1504 #if __USE_FORTIFY_LEVEL >= 1
1505       CHK_FAIL_START
1506       wchar_t wsmallbuf[2];
1507       cp = "ABC";
1508       mbsrtowcs (wsmallbuf, &cp, 10, &s);
1509       CHK_FAIL_END
1510 #endif
1511
1512       /* Bug 29030 regresion check */
1513       cp = "HelloWorld";
1514       if (mbsrtowcs (NULL, &cp, (size_t)-1, &s) != 10)
1515         FAIL ();
1516
1517       cp = "A";
1518       if (mbstowcs (wenough, cp, 10) != 1
1519           || wcscmp (wenough, L"A") != 0)
1520         FAIL ();
1521
1522       cp = "DEF";
1523       if (mbstowcs (wenough, cp, l0 + 10) != 3
1524           || wcscmp (wenough, L"DEF") != 0)
1525         FAIL ();
1526
1527 #if __USE_FORTIFY_LEVEL >= 1
1528       CHK_FAIL_START
1529       wchar_t wsmallbuf[2];
1530       cp = "ABC";
1531       mbstowcs (wsmallbuf, cp, 10);
1532       CHK_FAIL_END
1533 #endif
1534
1535       memset (&s, '\0', sizeof (s));
1536       cp = "ABC";
1537       wcscpy (wenough, L"DEF");
1538       if (mbsnrtowcs (wenough, &cp, 1, 10, &s) != 1
1539           || wcscmp (wenough, L"AEF") != 0)
1540         FAIL ();
1541
1542       cp = "IJ";
1543       if (mbsnrtowcs (wenough, &cp, 1, l0 + 10, &s) != 1
1544           || wcscmp (wenough, L"IEF") != 0)
1545         FAIL ();
1546
1547 #if __USE_FORTIFY_LEVEL >= 1
1548       CHK_FAIL_START
1549       wchar_t wsmallbuf[2];
1550       cp = "ABC";
1551       mbsnrtowcs (wsmallbuf, &cp, 3, 10, &s);
1552       CHK_FAIL_END
1553 #endif
1554
1555       memset (&s, '\0', sizeof (s));
1556       const wchar_t *wcp = L"A";
1557       if (wcsrtombs (enough, &wcp, 10, &s) != 1
1558           || strcmp (enough, "A") != 0)
1559         FAIL ();
1560
1561       wcp = L"BC";
1562       if (wcsrtombs (enough, &wcp, l0 + 10, &s) != 2
1563           || strcmp (enough, "BC") != 0)
1564         FAIL ();
1565
1566 #if __USE_FORTIFY_LEVEL >= 1
1567       CHK_FAIL_START
1568       char smallbuf[2];
1569       wcp = L"ABC";
1570       wcsrtombs (smallbuf, &wcp, 10, &s);
1571       CHK_FAIL_END
1572 #endif
1573
1574       memset (enough, 'Z', sizeof (enough));
1575       wcp = L"EF";
1576       if (wcstombs (enough, wcp, 10) != 2
1577           || strcmp (enough, "EF") != 0)
1578         FAIL ();
1579
1580       wcp = L"G";
1581       if (wcstombs (enough, wcp, l0 + 10) != 1
1582           || strcmp (enough, "G") != 0)
1583         FAIL ();
1584
1585 #if __USE_FORTIFY_LEVEL >= 1
1586       CHK_FAIL_START
1587       char smallbuf[2];
1588       wcp = L"ABC";
1589       wcstombs (smallbuf, wcp, 10);
1590       CHK_FAIL_END
1591 #endif
1592
1593       memset (&s, '\0', sizeof (s));
1594       wcp = L"AB";
1595       if (wcsnrtombs (enough, &wcp, 1, 10, &s) != 1
1596           || strcmp (enough, "A") != 0)
1597         FAIL ();
1598
1599       wcp = L"BCD";
1600       if (wcsnrtombs (enough, &wcp, 1, l0 + 10, &s) != 1
1601           || strcmp (enough, "B") != 0)
1602         FAIL ();
1603
1604 #if __USE_FORTIFY_LEVEL >= 1
1605       CHK_FAIL_START
1606       char smallbuf[2];
1607       wcp = L"ABC";
1608       wcsnrtombs (smallbuf, &wcp, 3, 10, &s);
1609       CHK_FAIL_END
1610 #endif
1611     }
1612   else
1613     {
1614       puts ("cannot set locale");
1615       ret = 1;
1616     }
1617
1618   int fd;
1619
1620 #ifdef _GNU_SOURCE
1621   fd = posix_openpt (O_RDWR);
1622   if (fd != -1)
1623     {
1624       char enough[1000];
1625       if (ptsname_r (fd, enough, sizeof (enough)) != 0)
1626         FAIL ();
1627
1628 #if __USE_FORTIFY_LEVEL >= 1
1629       CHK_FAIL_START
1630       char smallbuf[2];
1631       if (ptsname_r (fd, smallbuf, sizeof (smallbuf) + 1) == 0)
1632         FAIL ();
1633       CHK_FAIL_END
1634 #endif
1635       close (fd);
1636     }
1637 #endif
1638
1639 #if PATH_MAX > 0
1640   confstr (_CS_GNU_LIBC_VERSION, largebuf, sizeof (largebuf));
1641 # if __USE_FORTIFY_LEVEL >= 1
1642   CHK_FAIL_START
1643   char smallbuf[1];
1644   confstr (_CS_GNU_LIBC_VERSION, smallbuf, sizeof (largebuf));
1645   CHK_FAIL_END
1646 # endif
1647 #endif
1648
1649   gid_t grpslarge[5];
1650   int ngr = getgroups (5, grpslarge);
1651   asm volatile ("" : : "r" (ngr));
1652 #if __USE_FORTIFY_LEVEL >= 1
1653   CHK_FAIL_START
1654   char smallbuf[1];
1655   ngr = getgroups (5, (gid_t *) smallbuf);
1656   asm volatile ("" : : "r" (ngr));
1657   CHK_FAIL_END
1658 #endif
1659
1660   fd = open (_PATH_TTY, O_RDONLY);
1661   if (fd != -1)
1662     {
1663       char enough[1000];
1664       if (ttyname_r (fd, enough, sizeof (enough)) != 0)
1665         FAIL ();
1666
1667 #if __USE_FORTIFY_LEVEL >= 1
1668       CHK_FAIL_START
1669       char smallbuf[2];
1670       if (ttyname_r (fd, smallbuf, sizeof (smallbuf) + 1) == 0)
1671         FAIL ();
1672       CHK_FAIL_END
1673 #endif
1674       close (fd);
1675     }
1676
1677   char hostnamelarge[1000];
1678   gethostname (hostnamelarge, sizeof (hostnamelarge));
1679 #if __USE_FORTIFY_LEVEL >= 1
1680   CHK_FAIL_START
1681   char smallbuf[1];
1682   gethostname (smallbuf, sizeof (hostnamelarge));
1683   CHK_FAIL_END
1684 #endif
1685
1686   char loginlarge[1000];
1687   getlogin_r (loginlarge, sizeof (hostnamelarge));
1688 #if __USE_FORTIFY_LEVEL >= 1
1689   CHK_FAIL_START
1690   char smallbuf[1];
1691   getlogin_r (smallbuf, sizeof (loginlarge));
1692   CHK_FAIL_END
1693 #endif
1694
1695   char domainnamelarge[1000];
1696   int res = getdomainname (domainnamelarge, sizeof (domainnamelarge));
1697   asm volatile ("" : : "r" (res));
1698 #if __USE_FORTIFY_LEVEL >= 1
1699   CHK_FAIL_START
1700   char smallbuf[1];
1701   res = getdomainname (smallbuf, sizeof (domainnamelarge));
1702   asm volatile ("" : : "r" (res));
1703   CHK_FAIL_END
1704 #endif
1705
1706   fd_set s;
1707   FD_ZERO (&s);
1708
1709   FD_SET (FD_SETSIZE - 1, &s);
1710 #if __USE_FORTIFY_LEVEL >= 1
1711   CHK_FAIL_START
1712   FD_SET (FD_SETSIZE, &s);
1713   CHK_FAIL_END
1714
1715   CHK_FAIL_START
1716   FD_SET (l0 + FD_SETSIZE, &s);
1717   CHK_FAIL_END
1718 #endif
1719
1720   FD_CLR (FD_SETSIZE - 1, &s);
1721 #if __USE_FORTIFY_LEVEL >= 1
1722   CHK_FAIL_START
1723   FD_CLR (FD_SETSIZE, &s);
1724   CHK_FAIL_END
1725
1726   CHK_FAIL_START
1727   FD_SET (l0 + FD_SETSIZE, &s);
1728   CHK_FAIL_END
1729 #endif
1730
1731   FD_ISSET (FD_SETSIZE - 1, &s);
1732 #if __USE_FORTIFY_LEVEL >= 1
1733   CHK_FAIL_START
1734   FD_ISSET (FD_SETSIZE, &s);
1735   CHK_FAIL_END
1736
1737   CHK_FAIL_START
1738   FD_ISSET (l0 + FD_SETSIZE, &s);
1739   CHK_FAIL_END
1740 #endif
1741
1742   struct pollfd fds[1];
1743   fds[0].fd = STDOUT_FILENO;
1744   fds[0].events = POLLOUT;
1745   poll (fds, 1, 0);
1746 #if __USE_FORTIFY_LEVEL >= 1
1747   CHK_FAIL_START
1748   poll (fds, 2, 0);
1749   CHK_FAIL_END
1750
1751   CHK_FAIL_START
1752   poll (fds, l0 + 2, 0);
1753   CHK_FAIL_END
1754 #endif
1755 #ifdef _GNU_SOURCE
1756   ppoll (fds, 1, NULL, NULL);
1757 # if __USE_FORTIFY_LEVEL >= 1
1758   CHK_FAIL_START
1759   ppoll (fds, 2, NULL, NULL);
1760   CHK_FAIL_END
1761
1762   CHK_FAIL_START
1763   ppoll (fds, l0 + 2, NULL, NULL);
1764   CHK_FAIL_END
1765 # endif
1766 #endif
1767
1768   return ret;
1769 }