Add tests for __ptsname_r_chk, __realpath_chk, and __wctomb_chk.
[kopensolaris-gnu/glibc.git] / debug / tst-chk1.c
1 /* Copyright (C) 2004, 2005 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
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, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #include <fcntl.h>
21 #include <locale.h>
22 #include <paths.h>
23 #include <setjmp.h>
24 #include <signal.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <sys/socket.h>
29 #include <sys/un.h>
30 #include <unistd.h>
31
32 char *temp_filename;
33 static void do_prepare (void);
34 static int do_test (void);
35 #define PREPARE(argc, argv) do_prepare ()
36 #define TEST_FUNCTION do_test ()
37 #include "../test-skeleton.c"
38
39 static void
40 do_prepare (void)
41 {
42   int temp_fd = create_temp_file ("tst-chk1.", &temp_filename);
43   if (temp_fd == -1)
44     {
45       printf ("cannot create temporary file: %m\n");
46       exit (1);
47     }
48
49   const char *strs = "abcdefgh\nABCDEFGHI\nabcdefghij\nABCDEFGHIJ";
50   if (write (temp_fd, strs, strlen (strs)) != strlen (strs))
51     {
52       puts ("could not write test strings into file");
53       unlink (temp_filename);
54       exit (1);
55     }
56 }
57
58 volatile int chk_fail_ok;
59 volatile int ret;
60 jmp_buf chk_fail_buf;
61
62 static void
63 handler (int sig)
64 {
65   if (chk_fail_ok)
66     {
67       chk_fail_ok = 0;
68       longjmp (chk_fail_buf, 1);
69     }
70   else
71     _exit (127);
72 }
73
74 char buf[10];
75 volatile size_t l0;
76 volatile char *p;
77 const char *str1 = "JIHGFEDCBA";
78 const char *str2 = "F";
79 const char *str3 = "%s%n%s%n";
80 const char *str4 = "Hello, ";
81 const char *str5 = "World!\n";
82 char buf2[10] = "%s";
83 int num1 = 67;
84 int num2 = 987654;
85
86 #define FAIL() \
87   do { printf ("Failure on line %d\n", __LINE__); ret = 1; } while (0)
88 #define CHK_FAIL_START \
89   chk_fail_ok = 1;                              \
90   if (! setjmp (chk_fail_buf))                  \
91     {
92 #define CHK_FAIL_END \
93       chk_fail_ok = 0;                          \
94       FAIL ();                                  \
95     }
96 #if __USE_FORTIFY_LEVEL >= 2
97 #define CHK_FAIL2_START CHK_FAIL_START
98 #define CHK_FAIL2_END CHK_FAIL_END
99 #else
100 #define CHK_FAIL2_START
101 #define CHK_FAIL2_END
102 #endif
103
104 static int
105 do_test (void)
106 {
107   struct sigaction sa;
108   sa.sa_handler = handler;
109   sa.sa_flags = 0;
110   sigemptyset (&sa.sa_mask);
111
112   sigaction (SIGABRT, &sa, NULL);
113
114   /* Avoid all the buffer overflow messages on stderr.  */
115   int fd = open (_PATH_DEVNULL, O_WRONLY);
116   if (fd == -1)
117     close (STDERR_FILENO);
118   else
119     {
120       dup2 (fd, STDERR_FILENO);
121       close (fd);
122     }
123   setenv ("LIBC_FATAL_STDERR_", "1", 1);
124
125   struct A { char buf1[9]; char buf2[1]; } a;
126
127   printf ("Test checking routines at fortify level %d\n",
128 #ifdef __USE_FORTIFY_LEVEL
129           (int) __USE_FORTIFY_LEVEL
130 #else
131           0
132 #endif
133           );
134
135   /* These ops can be done without runtime checking of object size.  */
136   memcpy (buf, "abcdefghij", 10);
137   memmove (buf + 1, buf, 9);
138   if (memcmp (buf, "aabcdefghi", 10))
139     FAIL ();
140
141   if (mempcpy (buf + 5, "abcde", 5) != buf + 10 || memcmp (buf, "aabcdabcde", 10))
142     FAIL ();
143
144   memset (buf + 8, 'j', 2);
145   if (memcmp (buf, "aabcdabcjj", 10))
146     FAIL ();
147
148   strcpy (buf + 4, "EDCBA");
149   if (memcmp (buf, "aabcEDCBA", 10))
150     FAIL ();
151
152   if (stpcpy (buf + 8, "F") != buf + 9 || memcmp (buf, "aabcEDCBF", 10))
153     FAIL ();
154
155   strncpy (buf + 6, "X", 4);
156   if (memcmp (buf, "aabcEDX\0\0", 10))
157     FAIL ();
158
159   if (sprintf (buf + 7, "%s", "67") != 2 || memcmp (buf, "aabcEDX67", 10))
160     FAIL ();
161
162   if (snprintf (buf + 7, 3, "%s", "987654") != 6
163       || memcmp (buf, "aabcEDX98", 10))
164     FAIL ();
165
166   /* These ops need runtime checking, but shouldn't __chk_fail.  */
167   memcpy (buf, "abcdefghij", l0 + 10);
168   memmove (buf + 1, buf, l0 + 9);
169   if (memcmp (buf, "aabcdefghi", 10))
170     FAIL ();
171
172   if (mempcpy (buf + 5, "abcde", l0 + 5) != buf + 10 || memcmp (buf, "aabcdabcde", 10))
173     FAIL ();
174
175   memset (buf + 8, 'j', l0 + 2);
176   if (memcmp (buf, "aabcdabcjj", 10))
177     FAIL ();
178
179   strcpy (buf + 4, str1 + 5);
180   if (memcmp (buf, "aabcEDCBA", 10))
181     FAIL ();
182
183   if (stpcpy (buf + 8, str2) != buf + 9 || memcmp (buf, "aabcEDCBF", 10))
184     FAIL ();
185
186   strncpy (buf + 6, "X", l0 + 4);
187   if (memcmp (buf, "aabcEDX\0\0", 10))
188     FAIL ();
189
190   if (sprintf (buf + 7, "%d", num1) != 2 || memcmp (buf, "aabcEDX67", 10))
191     FAIL ();
192
193   if (snprintf (buf + 7, 3, "%d", num2) != 6 || memcmp (buf, "aabcEDX98", 10))
194     FAIL ();
195
196   buf[l0 + 8] = '\0';
197   strcat (buf, "A");
198   if (memcmp (buf, "aabcEDX9A", 10))
199     FAIL ();
200
201   buf[l0 + 7] = '\0';
202   strncat (buf, "ZYXWV", l0 + 2);
203   if (memcmp (buf, "aabcEDXZY", 10))
204     FAIL ();
205
206   memcpy (a.buf1, "abcdefghij", l0 + 10);
207   memmove (a.buf1 + 1, a.buf1, l0 + 9);
208   if (memcmp (a.buf1, "aabcdefghi", 10))
209     FAIL ();
210
211   if (mempcpy (a.buf1 + 5, "abcde", l0 + 5) != a.buf1 + 10
212       || memcmp (a.buf1, "aabcdabcde", 10))
213     FAIL ();
214
215   memset (a.buf1 + 8, 'j', l0 + 2);
216   if (memcmp (a.buf1, "aabcdabcjj", 10))
217     FAIL ();
218
219 #if __USE_FORTIFY_LEVEL < 2
220   /* The following tests are supposed to crash with -D_FORTIFY_SOURCE=2
221      and sufficient GCC support, as the string operations overflow
222      from a.buf1 into a.buf2.  */
223   strcpy (a.buf1 + 4, str1 + 5);
224   if (memcmp (a.buf1, "aabcEDCBA", 10))
225     FAIL ();
226
227   if (stpcpy (a.buf1 + 8, str2) != a.buf1 + 9 || memcmp (a.buf1, "aabcEDCBF", 10))
228     FAIL ();
229
230   strncpy (a.buf1 + 6, "X", l0 + 4);
231   if (memcmp (a.buf1, "aabcEDX\0\0", 10))
232     FAIL ();
233
234   if (sprintf (a.buf1 + 7, "%d", num1) != 2 || memcmp (a.buf1, "aabcEDX67", 10))
235     FAIL ();
236
237   if (snprintf (a.buf1 + 7, 3, "%d", num2) != 6
238       || memcmp (a.buf1, "aabcEDX98", 10))
239     FAIL ();
240
241   a.buf1[l0 + 8] = '\0';
242   strcat (a.buf1, "A");
243   if (memcmp (a.buf1, "aabcEDX9A", 10))
244     FAIL ();
245
246   a.buf1[l0 + 7] = '\0';
247   strncat (a.buf1, "ZYXWV", l0 + 2);
248   if (memcmp (a.buf1, "aabcEDXZY", 10))
249     FAIL ();
250
251 #endif
252
253 #if __USE_FORTIFY_LEVEL >= 1
254   /* Now check if all buffer overflows are caught at runtime.  */
255
256   CHK_FAIL_START
257   memcpy (buf + 1, "abcdefghij", l0 + 10);
258   CHK_FAIL_END
259
260   CHK_FAIL_START
261   memmove (buf + 2, buf + 1, l0 + 9);
262   CHK_FAIL_END
263
264   CHK_FAIL_START
265   p = mempcpy (buf + 6, "abcde", l0 + 5);
266   CHK_FAIL_END
267
268   CHK_FAIL_START
269   memset (buf + 9, 'j', l0 + 2);
270   CHK_FAIL_END
271
272   CHK_FAIL_START
273   strcpy (buf + 5, str1 + 5);
274   CHK_FAIL_END
275
276   CHK_FAIL_START
277   p = stpcpy (buf + 9, str2);
278   CHK_FAIL_END
279
280   CHK_FAIL_START
281   strncpy (buf + 7, "X", l0 + 4);
282   CHK_FAIL_END
283
284   CHK_FAIL_START
285   sprintf (buf + 8, "%d", num1);
286   CHK_FAIL_END
287
288   CHK_FAIL_START
289   snprintf (buf + 8, l0 + 3, "%d", num2);
290   CHK_FAIL_END
291
292   memcpy (buf, str1 + 2, l0 + 9);
293   CHK_FAIL_START
294   strcat (buf, "AB");
295   CHK_FAIL_END
296
297   memcpy (buf, str1 + 3, l0 + 8);
298   CHK_FAIL_START
299   strncat (buf, "ZYXWV", l0 + 3);
300   CHK_FAIL_END
301
302   CHK_FAIL_START
303   memcpy (a.buf1 + 1, "abcdefghij", l0 + 10);
304   CHK_FAIL_END
305
306   CHK_FAIL_START
307   memmove (a.buf1 + 2, a.buf1 + 1, l0 + 9);
308   CHK_FAIL_END
309
310   CHK_FAIL_START
311   p = mempcpy (a.buf1 + 6, "abcde", l0 + 5);
312   CHK_FAIL_END
313
314   CHK_FAIL_START
315   memset (a.buf1 + 9, 'j', l0 + 2);
316   CHK_FAIL_END
317
318 #if __USE_FORTIFY_LEVEL >= 2
319 # define O 0
320 #else
321 # define O 1
322 #endif
323
324   CHK_FAIL_START
325   strcpy (a.buf1 + (O + 4), str1 + 5);
326   CHK_FAIL_END
327
328   CHK_FAIL_START
329   p = stpcpy (a.buf1 + (O + 8), str2);
330   CHK_FAIL_END
331
332   CHK_FAIL_START
333   strncpy (a.buf1 + (O + 6), "X", l0 + 4);
334   CHK_FAIL_END
335
336   CHK_FAIL_START
337   sprintf (a.buf1 + (O + 7), "%d", num1);
338   CHK_FAIL_END
339
340   CHK_FAIL_START
341   snprintf (a.buf1 + (O + 7), l0 + 3, "%d", num2);
342   CHK_FAIL_END
343
344   memcpy (a.buf1, str1 + (3 - O), l0 + 8 + O);
345   CHK_FAIL_START
346   strcat (a.buf1, "AB");
347   CHK_FAIL_END
348
349   memcpy (a.buf1, str1 + (4 - O), l0 + 7 + O);
350   CHK_FAIL_START
351   strncat (a.buf1, "ZYXWV", l0 + 3);
352   CHK_FAIL_END
353 #endif
354
355   /* Now checks for %n protection.  */
356
357   /* Constant literals passed directly are always ok
358      (even with warnings about possible bugs from GCC).  */
359   int n1, n2;
360   if (sprintf (buf, "%s%n%s%n", str2, &n1, str2, &n2) != 2
361       || n1 != 1 || n2 != 2)
362     FAIL ();
363
364   /* In this case the format string is not known at compile time,
365      but resides in read-only memory, so is ok.  */
366   if (snprintf (buf, 4, str3, str2, &n1, str2, &n2) != 2
367       || n1 != 1 || n2 != 2)
368     FAIL ();
369
370   strcpy (buf2 + 2, "%n%s%n");
371   /* When the format string is writable and contains %n,
372      with -D_FORTIFY_SOURCE=2 it causes __chk_fail.  */
373   CHK_FAIL2_START
374   if (sprintf (buf, buf2, str2, &n1, str2, &n1) != 2)
375     FAIL ();
376   CHK_FAIL2_END
377
378   CHK_FAIL2_START
379   if (snprintf (buf, 3, buf2, str2, &n1, str2, &n1) != 2)
380     FAIL ();
381   CHK_FAIL2_END
382
383   /* But if there is no %n, even writable format string
384      should work.  */
385   buf2[6] = '\0';
386   if (sprintf (buf, buf2 + 4, str2) != 1)
387     FAIL ();
388
389   /* Constant literals passed directly are always ok
390      (even with warnings about possible bugs from GCC).  */
391   if (printf ("%s%n%s%n", str4, &n1, str5, &n2) != 14
392       || n1 != 7 || n2 != 14)
393     FAIL ();
394
395   /* In this case the format string is not known at compile time,
396      but resides in read-only memory, so is ok.  */
397   if (printf (str3, str4, &n1, str5, &n2) != 14
398       || n1 != 7 || n2 != 14)
399     FAIL ();
400
401   strcpy (buf2 + 2, "%n%s%n");
402   /* When the format string is writable and contains %n,
403      with -D_FORTIFY_SOURCE=2 it causes __chk_fail.  */
404   CHK_FAIL2_START
405   if (printf (buf2, str4, &n1, str5, &n1) != 14)
406     FAIL ();
407   CHK_FAIL2_END
408
409   /* But if there is no %n, even writable format string
410      should work.  */
411   buf2[6] = '\0';
412   if (printf (buf2 + 4, str5) != 7)
413     FAIL ();
414
415   FILE *fp = stdout;
416
417   /* Constant literals passed directly are always ok
418      (even with warnings about possible bugs from GCC).  */
419   if (fprintf (fp, "%s%n%s%n", str4, &n1, str5, &n2) != 14
420       || n1 != 7 || n2 != 14)
421     FAIL ();
422
423   /* In this case the format string is not known at compile time,
424      but resides in read-only memory, so is ok.  */
425   if (fprintf (fp, str3, str4, &n1, str5, &n2) != 14
426       || n1 != 7 || n2 != 14)
427     FAIL ();
428
429   strcpy (buf2 + 2, "%n%s%n");
430   /* When the format string is writable and contains %n,
431      with -D_FORTIFY_SOURCE=2 it causes __chk_fail.  */
432   CHK_FAIL2_START
433   if (fprintf (fp, buf2, str4, &n1, str5, &n1) != 14)
434     FAIL ();
435   CHK_FAIL2_END
436
437   /* But if there is no %n, even writable format string
438      should work.  */
439   buf2[6] = '\0';
440   if (fprintf (fp, buf2 + 4, str5) != 7)
441     FAIL ();
442
443   if (freopen (temp_filename, "r", stdin) == NULL)
444     {
445       puts ("could not open temporary file");
446       exit (1);
447     }
448
449   if (gets (buf) != buf || memcmp (buf, "abcdefgh", 9))
450     FAIL ();
451   if (gets (buf) != buf || memcmp (buf, "ABCDEFGHI", 10))
452     FAIL ();
453
454 #if __USE_FORTIFY_LEVEL >= 1
455   CHK_FAIL_START
456   if (gets (buf) != buf)
457     FAIL ();
458   CHK_FAIL_END
459 #endif
460
461   rewind (stdin);
462
463   if (fgets (buf, sizeof (buf), stdin) != buf
464       || memcmp (buf, "abcdefgh\n", 10))
465     FAIL ();
466   if (fgets (buf, sizeof (buf), stdin) != buf || memcmp (buf, "ABCDEFGHI", 10))
467     FAIL ();
468
469   rewind (stdin);
470
471   if (fgets (buf, l0 + sizeof (buf), stdin) != buf
472       || memcmp (buf, "abcdefgh\n", 10))
473     FAIL ();
474
475 #if __USE_FORTIFY_LEVEL >= 1
476   CHK_FAIL_START
477   if (fgets (buf, sizeof (buf) + 1, stdin) != buf)
478     FAIL ();
479   CHK_FAIL_END
480
481   CHK_FAIL_START
482   if (fgets (buf, l0 + sizeof (buf) + 1, stdin) != buf)
483     FAIL ();
484   CHK_FAIL_END
485 #endif
486
487   rewind (stdin);
488
489   if (fgets_unlocked (buf, sizeof (buf), stdin) != buf
490       || memcmp (buf, "abcdefgh\n", 10))
491     FAIL ();
492   if (fgets_unlocked (buf, sizeof (buf), stdin) != buf
493       || memcmp (buf, "ABCDEFGHI", 10))
494     FAIL ();
495
496   rewind (stdin);
497
498   if (fgets_unlocked (buf, l0 + sizeof (buf), stdin) != buf
499       || memcmp (buf, "abcdefgh\n", 10))
500     FAIL ();
501
502 #if __USE_FORTIFY_LEVEL >= 1
503   CHK_FAIL_START
504   if (fgets_unlocked (buf, sizeof (buf) + 1, stdin) != buf)
505     FAIL ();
506   CHK_FAIL_END
507
508   CHK_FAIL_START
509   if (fgets_unlocked (buf, l0 + sizeof (buf) + 1, stdin) != buf)
510     FAIL ();
511   CHK_FAIL_END
512 #endif
513
514   lseek (fileno (stdin), 0, SEEK_SET);
515
516   if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1
517       || memcmp (buf, "abcdefgh\n", 9))
518     FAIL ();
519   if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1
520       || memcmp (buf, "ABCDEFGHI", 9))
521     FAIL ();
522
523   lseek (fileno (stdin), 0, SEEK_SET);
524
525   if (read (fileno (stdin), buf, l0 + sizeof (buf) - 1) != sizeof (buf) - 1
526       || memcmp (buf, "abcdefgh\n", 9))
527     FAIL ();
528
529 #if __USE_FORTIFY_LEVEL >= 1
530   CHK_FAIL_START
531   if (read (fileno (stdin), buf, sizeof (buf) + 1) != sizeof (buf) + 1)
532     FAIL ();
533   CHK_FAIL_END
534 #endif
535
536   if (pread (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2)
537       != sizeof (buf) - 1
538       || memcmp (buf, "\nABCDEFGH", 9))
539     FAIL ();
540   if (pread (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1
541       || memcmp (buf, "abcdefgh\n", 9))
542     FAIL ();
543   if (pread (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3)
544       != sizeof (buf) - 1
545       || memcmp (buf, "h\nABCDEFG", 9))
546     FAIL ();
547
548 #if __USE_FORTIFY_LEVEL >= 1
549   CHK_FAIL_START
550   if (pread (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf))
551       != sizeof (buf) + 1)
552     FAIL ();
553   CHK_FAIL_END
554 #endif
555
556   if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2)
557       != sizeof (buf) - 1
558       || memcmp (buf, "\nABCDEFGH", 9))
559     FAIL ();
560   if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1
561       || memcmp (buf, "abcdefgh\n", 9))
562     FAIL ();
563   if (pread64 (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3)
564       != sizeof (buf) - 1
565       || memcmp (buf, "h\nABCDEFG", 9))
566     FAIL ();
567
568 #if __USE_FORTIFY_LEVEL >= 1
569   CHK_FAIL_START
570   if (pread64 (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf))
571       != sizeof (buf) + 1)
572     FAIL ();
573   CHK_FAIL_END
574 #endif
575
576   if (freopen (temp_filename, "r", stdin) == NULL)
577     {
578       puts ("could not open temporary file");
579       exit (1);
580     }
581
582   if (fseek (stdin, 9 + 10 + 11, SEEK_SET))
583     {
584       puts ("could not seek in test file");
585       exit (1);
586     }
587
588 #if __USE_FORTIFY_LEVEL >= 1
589   CHK_FAIL_START
590   if (gets (buf) != buf)
591     FAIL ();
592   CHK_FAIL_END
593 #endif
594
595   /* Check whether missing N$ formats are detected.  */
596   CHK_FAIL2_START
597   printf ("%3$d\n", 1, 2, 3, 4);
598   CHK_FAIL2_END
599
600   CHK_FAIL2_START
601   fprintf (stdout, "%3$d\n", 1, 2, 3, 4);
602   CHK_FAIL2_END
603
604   CHK_FAIL2_START
605   sprintf (buf, "%3$d\n", 1, 2, 3, 4);
606   CHK_FAIL2_END
607
608   CHK_FAIL2_START
609   snprintf (buf, sizeof (buf), "%3$d\n", 1, 2, 3, 4);
610   CHK_FAIL2_END
611
612   int sp[2];
613   if (socketpair (PF_UNIX, SOCK_STREAM, 0, sp))
614     FAIL ();
615   else
616     {
617       const char *sendstr = "abcdefgh\nABCDEFGH\n0123456789\n";
618       if (send (sp[0], sendstr, strlen (sendstr), 0) != strlen (sendstr))
619         FAIL ();
620
621       char recvbuf[12];
622       if (recv (sp[1], recvbuf, sizeof recvbuf, MSG_PEEK)
623           != sizeof recvbuf
624           || memcmp (recvbuf, sendstr, sizeof recvbuf) != 0)
625         FAIL ();
626
627       if (recv (sp[1], recvbuf + 6, l0 + sizeof recvbuf - 7, MSG_PEEK)
628           != sizeof recvbuf - 7
629           || memcmp (recvbuf + 6, sendstr, sizeof recvbuf - 7) != 0)
630         FAIL ();
631
632 #if __USE_FORTIFY_LEVEL >= 1
633       CHK_FAIL_START
634       if (recv (sp[1], recvbuf + 1, sizeof recvbuf, MSG_PEEK)
635           != sizeof recvbuf)
636         FAIL ();
637       CHK_FAIL_END
638
639       CHK_FAIL_START
640       if (recv (sp[1], recvbuf + 4, l0 + sizeof recvbuf - 3, MSG_PEEK)
641           != sizeof recvbuf - 3)
642         FAIL ();
643       CHK_FAIL_END
644 #endif
645
646       socklen_t sl;
647       struct sockaddr_un sa_un;
648
649       sl = sizeof (sa_un);
650       if (recvfrom (sp[1], recvbuf, sizeof recvbuf, MSG_PEEK, &sa_un, &sl)
651           != sizeof recvbuf
652           || memcmp (recvbuf, sendstr, sizeof recvbuf) != 0)
653         FAIL ();
654
655       sl = sizeof (sa_un);
656       if (recvfrom (sp[1], recvbuf + 6, l0 + sizeof recvbuf - 7, MSG_PEEK,
657           &sa_un, &sl) != sizeof recvbuf - 7
658           || memcmp (recvbuf + 6, sendstr, sizeof recvbuf - 7) != 0)
659         FAIL ();
660
661 #if __USE_FORTIFY_LEVEL >= 1
662       CHK_FAIL_START
663       sl = sizeof (sa_un);
664       if (recvfrom (sp[1], recvbuf + 1, sizeof recvbuf, MSG_PEEK, &sa_un, &sl)
665           != sizeof recvbuf)
666         FAIL ();
667       CHK_FAIL_END
668
669       CHK_FAIL_START
670       sl = sizeof (sa_un);
671       if (recvfrom (sp[1], recvbuf + 4, l0 + sizeof recvbuf - 3, MSG_PEEK,
672           &sa_un, &sl) != sizeof recvbuf - 3)
673         FAIL ();
674       CHK_FAIL_END
675 #endif
676
677       close (sp[0]);
678       close (sp[1]);
679     }
680
681   char fname[] = "/tmp/tst-chk1-dir-XXXXXX\0foo";
682   char *enddir = strchr (fname, '\0');
683   if (mkdtemp (fname) == NULL)
684     {
685       printf ("mkdtemp failed: %m\n");
686       return 1;
687     }
688   *enddir = '/';
689   if (symlink ("bar", fname) != 0)
690     FAIL ();
691
692   char readlinkbuf[4];
693   if (readlink (fname, readlinkbuf, 4) != 3
694       || memcmp (readlinkbuf, "bar", 3) != 0)
695     FAIL ();
696   if (readlink (fname, readlinkbuf + 1, l0 + 3) != 3
697       || memcmp (readlinkbuf, "bbar", 4) != 0)
698     FAIL ();
699
700 #if __USE_FORTIFY_LEVEL >= 1
701   CHK_FAIL_START
702   if (readlink (fname, readlinkbuf + 2, l0 + 3) != 3)
703     FAIL ();
704   CHK_FAIL_END
705
706   CHK_FAIL_START
707   if (readlink (fname, readlinkbuf + 3, 4) != 3)
708     FAIL ();
709   CHK_FAIL_END
710 #endif
711
712   char *cwd1 = getcwd (NULL, 0);
713   if (cwd1 == NULL)
714     FAIL ();
715
716   char *cwd2 = getcwd (NULL, 250);
717   if (cwd2 == NULL)
718     FAIL ();
719
720   if (cwd1 && cwd2)
721     {
722       if (strcmp (cwd1, cwd2) != 0)
723         FAIL ();
724
725       *enddir = '\0';
726       if (chdir (fname))
727         FAIL ();
728
729       char *cwd3 = getcwd (NULL, 0);
730       if (cwd3 == NULL)
731         FAIL ();
732       if (strcmp (fname, cwd3) != 0)
733         printf ("getcwd after chdir is '%s' != '%s',"
734                 "get{c,}wd tests skipped\n", cwd3, fname);
735       else
736         {
737           char getcwdbuf[sizeof fname - 3];
738
739           char *cwd4 = getcwd (getcwdbuf, sizeof getcwdbuf);
740           if (cwd4 != getcwdbuf
741               || strcmp (getcwdbuf, fname) != 0)
742             FAIL ();
743
744           cwd4 = getcwd (getcwdbuf + 1, l0 + sizeof getcwdbuf - 1);
745           if (cwd4 != getcwdbuf + 1
746               || getcwdbuf[0] != fname[0]
747               || strcmp (getcwdbuf + 1, fname) != 0)
748             FAIL ();
749
750 #if __USE_FORTIFY_LEVEL >= 1
751           CHK_FAIL_START
752           if (getcwd (getcwdbuf + 2, l0 + sizeof getcwdbuf)
753               != getcwdbuf + 2)
754             FAIL ();
755           CHK_FAIL_END
756
757           CHK_FAIL_START
758           if (getcwd (getcwdbuf + 2, sizeof getcwdbuf)
759               != getcwdbuf + 2)
760             FAIL ();
761           CHK_FAIL_END
762 #endif
763
764           if (getwd (getcwdbuf) != getcwdbuf
765               || strcmp (getcwdbuf, fname) != 0)
766             FAIL ();
767
768           if (getwd (getcwdbuf + 1) != getcwdbuf + 1
769               || strcmp (getcwdbuf + 1, fname) != 0)
770             FAIL ();
771
772 #if __USE_FORTIFY_LEVEL >= 1
773           CHK_FAIL_START
774           if (getwd (getcwdbuf + 2) != getcwdbuf + 2)
775             FAIL ();
776           CHK_FAIL_END
777 #endif
778         }
779
780       if (chdir (cwd1) != 0)
781         FAIL ();
782       free (cwd3);
783     }
784
785   free (cwd1);
786   free (cwd2);
787   *enddir = '/';
788   if (unlink (fname) != 0)
789     FAIL ();
790
791   *enddir = '\0';
792   if (rmdir (fname) != 0)
793     FAIL ();
794
795
796 #if PATH_MAX > 0
797   char largebuf[PATH_MAX];
798   char *realres = realpath (".", largebuf);
799 #endif
800 #if __USE_FORTIFY_LEVEL >= 1
801   CHK_FAIL_START
802   char realbuf[1];
803   realres = realpath (".", realbuf);
804   CHK_FAIL_END
805 #endif
806
807   if (setlocale (LC_ALL, "de_DE.UTF-8") != NULL)
808     {
809       /* First a simple test.  */
810       char enough[MB_CUR_MAX];
811       if (wctomb (enough, L'A') != 1)
812         {
813           puts ("first wctomb test failed");
814           ret = 1;
815         }
816
817 #if __USE_FORTIFY_LEVEL >= 1
818       /* We know the wchar_t encoding is ISO 10646.  So pick a
819          character which has a multibyte representation which does not
820          fit.  */
821       CHK_FAIL_START
822       char smallbuf[2];
823       if (wctomb (smallbuf, L'\x100') != 2)
824         {
825           puts ("second wctomb test failed");
826           ret = 1;
827         }
828       CHK_FAIL_END
829 #endif
830     }
831   else
832     {
833       puts ("cannot set locale");
834       ret = 1;
835     }
836
837   fd = posix_openpt (O_RDWR);
838   if (fd != -1)
839     {
840       char enough[1000];
841       if (ptsname_r (fd, enough, sizeof (enough)) != 0)
842         {
843           puts ("first ptsname_r failed");
844           ret = 1;
845         }
846
847 #if __USE_FORTIFY_LEVEL >= 1
848       CHK_FAIL_START
849       char smallbuf[2];
850       if (ptsname_r (fd, smallbuf, sizeof (smallbuf) + 1) == 0)
851         {
852           puts ("second ptsname_r somehow suceeded");
853           ret = 1;
854         }
855       CHK_FAIL_END
856 #endif
857     }
858
859   return ret;
860 }