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