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.
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.
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.
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
20 /* Hack: make sure GCC doesn't know __chk_fail () will not return. */
30 #include <sys/socket.h>
35 static void do_prepare (void);
36 static int do_test (void);
37 #define PREPARE(argc, argv) do_prepare ()
38 #define TEST_FUNCTION do_test ()
39 #include "../test-skeleton.c"
44 int temp_fd
= create_temp_file ("tst-chk1.", &temp_filename
);
47 printf ("cannot create temporary file: %m\n");
51 const char *strs
= "abcdefgh\nABCDEFGHI\nabcdefghij\nABCDEFGHIJ";
52 if (write (temp_fd
, strs
, strlen (strs
)) != strlen (strs
))
54 puts ("could not write test strings into file");
55 unlink (temp_filename
);
60 volatile int chk_fail_ok
;
70 longjmp (chk_fail_buf
, 1);
79 const char *str1
= "JIHGFEDCBA";
80 const char *str2
= "F";
81 const char *str3
= "%s%n%s%n";
82 const char *str4
= "Hello, ";
83 const char *str5
= "World!\n";
89 do { printf ("Failure on line %d\n", __LINE__); ret = 1; } while (0)
90 #define CHK_FAIL_START \
92 if (! setjmp (chk_fail_buf)) \
94 #define CHK_FAIL_END \
98 #if __USE_FORTIFY_LEVEL >= 2
99 #define CHK_FAIL2_START CHK_FAIL_START
100 #define CHK_FAIL2_END CHK_FAIL_END
102 #define CHK_FAIL2_START
103 #define CHK_FAIL2_END
110 sa
.sa_handler
= handler
;
112 sigemptyset (&sa
.sa_mask
);
114 sigaction (SIGABRT
, &sa
, NULL
);
116 /* Avoid all the buffer overflow messages on stderr. */
117 int fd
= open (_PATH_DEVNULL
, O_WRONLY
);
119 close (STDERR_FILENO
);
122 dup2 (fd
, STDERR_FILENO
);
125 setenv ("LIBC_FATAL_STDERR_", "1", 1);
127 struct A
{ char buf1
[9]; char buf2
[1]; } a
;
129 printf ("Test checking routines at fortify level %d\n",
130 #ifdef __USE_FORTIFY_LEVEL
131 (int) __USE_FORTIFY_LEVEL
137 /* These ops can be done without runtime checking of object size. */
138 memcpy (buf
, "abcdefghij", 10);
139 memmove (buf
+ 1, buf
, 9);
140 if (memcmp (buf
, "aabcdefghi", 10))
143 if (mempcpy (buf
+ 5, "abcde", 5) != buf
+ 10 || memcmp (buf
, "aabcdabcde", 10))
146 memset (buf
+ 8, 'j', 2);
147 if (memcmp (buf
, "aabcdabcjj", 10))
150 strcpy (buf
+ 4, "EDCBA");
151 if (memcmp (buf
, "aabcEDCBA", 10))
154 if (stpcpy (buf
+ 8, "F") != buf
+ 9 || memcmp (buf
, "aabcEDCBF", 10))
157 strncpy (buf
+ 6, "X", 4);
158 if (memcmp (buf
, "aabcEDX\0\0", 10))
161 if (sprintf (buf
+ 7, "%s", "67") != 2 || memcmp (buf
, "aabcEDX67", 10))
164 if (snprintf (buf
+ 7, 3, "%s", "987654") != 6
165 || memcmp (buf
, "aabcEDX98", 10))
168 /* These ops need runtime checking, but shouldn't __chk_fail. */
169 memcpy (buf
, "abcdefghij", l0
+ 10);
170 memmove (buf
+ 1, buf
, l0
+ 9);
171 if (memcmp (buf
, "aabcdefghi", 10))
174 if (mempcpy (buf
+ 5, "abcde", l0
+ 5) != buf
+ 10 || memcmp (buf
, "aabcdabcde", 10))
177 memset (buf
+ 8, 'j', l0
+ 2);
178 if (memcmp (buf
, "aabcdabcjj", 10))
181 strcpy (buf
+ 4, str1
+ 5);
182 if (memcmp (buf
, "aabcEDCBA", 10))
185 if (stpcpy (buf
+ 8, str2
) != buf
+ 9 || memcmp (buf
, "aabcEDCBF", 10))
188 strncpy (buf
+ 6, "X", l0
+ 4);
189 if (memcmp (buf
, "aabcEDX\0\0", 10))
192 if (sprintf (buf
+ 7, "%d", num1
) != 2 || memcmp (buf
, "aabcEDX67", 10))
195 if (snprintf (buf
+ 7, 3, "%d", num2
) != 6 || memcmp (buf
, "aabcEDX98", 10))
200 if (memcmp (buf
, "aabcEDX9A", 10))
204 strncat (buf
, "ZYXWV", l0
+ 2);
205 if (memcmp (buf
, "aabcEDXZY", 10))
208 memcpy (a
.buf1
, "abcdefghij", l0
+ 10);
209 memmove (a
.buf1
+ 1, a
.buf1
, l0
+ 9);
210 if (memcmp (a
.buf1
, "aabcdefghi", 10))
213 if (mempcpy (a
.buf1
+ 5, "abcde", l0
+ 5) != a
.buf1
+ 10
214 || memcmp (a
.buf1
, "aabcdabcde", 10))
217 memset (a
.buf1
+ 8, 'j', l0
+ 2);
218 if (memcmp (a
.buf1
, "aabcdabcjj", 10))
221 #if __USE_FORTIFY_LEVEL < 2 || !__GNUC_PREREQ (4, 0)
222 /* The following tests are supposed to crash with -D_FORTIFY_SOURCE=2
223 and sufficient GCC support, as the string operations overflow
224 from a.buf1 into a.buf2. */
225 strcpy (a
.buf1
+ 4, str1
+ 5);
226 if (memcmp (a
.buf1
, "aabcEDCBA", 10))
229 if (stpcpy (a
.buf1
+ 8, str2
) != a
.buf1
+ 9 || memcmp (a
.buf1
, "aabcEDCBF", 10))
232 strncpy (a
.buf1
+ 6, "X", l0
+ 4);
233 if (memcmp (a
.buf1
, "aabcEDX\0\0", 10))
236 if (sprintf (a
.buf1
+ 7, "%d", num1
) != 2 || memcmp (a
.buf1
, "aabcEDX67", 10))
239 if (snprintf (a
.buf1
+ 7, 3, "%d", num2
) != 6
240 || memcmp (a
.buf1
, "aabcEDX98", 10))
243 a
.buf1
[l0
+ 8] = '\0';
244 strcat (a
.buf1
, "A");
245 if (memcmp (a
.buf1
, "aabcEDX9A", 10))
248 a
.buf1
[l0
+ 7] = '\0';
249 strncat (a
.buf1
, "ZYXWV", l0
+ 2);
250 if (memcmp (a
.buf1
, "aabcEDXZY", 10))
255 #if __USE_FORTIFY_LEVEL >= 1
256 /* Now check if all buffer overflows are caught at runtime. */
259 memcpy (buf
+ 1, "abcdefghij", l0
+ 10);
263 memmove (buf
+ 2, buf
+ 1, l0
+ 9);
267 p
= mempcpy (buf
+ 6, "abcde", l0
+ 5);
271 memset (buf
+ 9, 'j', l0
+ 2);
275 strcpy (buf
+ 5, str1
+ 5);
279 p
= stpcpy (buf
+ 9, str2
);
283 strncpy (buf
+ 7, "X", l0
+ 4);
287 sprintf (buf
+ 8, "%d", num1
);
291 snprintf (buf
+ 8, l0
+ 3, "%d", num2
);
294 memcpy (buf
, str1
+ 2, l0
+ 9);
299 memcpy (buf
, str1
+ 3, l0
+ 8);
301 strncat (buf
, "ZYXWV", l0
+ 3);
305 memcpy (a
.buf1
+ 1, "abcdefghij", l0
+ 10);
309 memmove (a
.buf1
+ 2, a
.buf1
+ 1, l0
+ 9);
313 p
= mempcpy (a
.buf1
+ 6, "abcde", l0
+ 5);
317 memset (a
.buf1
+ 9, 'j', l0
+ 2);
320 #if __USE_FORTIFY_LEVEL >= 2 && __GNUC_PREREQ (4, 0)
327 strcpy (a
.buf1
+ (O
+ 4), str1
+ 5);
331 p
= stpcpy (a
.buf1
+ (O
+ 8), str2
);
335 strncpy (a
.buf1
+ (O
+ 6), "X", l0
+ 4);
339 sprintf (a
.buf1
+ (O
+ 7), "%d", num1
);
343 snprintf (a
.buf1
+ (O
+ 7), l0
+ 3, "%d", num2
);
346 memcpy (a
.buf1
, str1
+ (3 - O
), l0
+ 8 + O
);
348 strcat (a
.buf1
, "AB");
351 memcpy (a
.buf1
, str1
+ (4 - O
), l0
+ 7 + O
);
353 strncat (a
.buf1
, "ZYXWV", l0
+ 3);
357 /* Now checks for %n protection. */
359 /* Constant literals passed directly are always ok
360 (even with warnings about possible bugs from GCC). */
362 if (sprintf (buf
, "%s%n%s%n", str2
, &n1
, str2
, &n2
) != 2
363 || n1
!= 1 || n2
!= 2)
366 /* In this case the format string is not known at compile time,
367 but resides in read-only memory, so is ok. */
368 if (snprintf (buf
, 4, str3
, str2
, &n1
, str2
, &n2
) != 2
369 || n1
!= 1 || n2
!= 2)
372 strcpy (buf2
+ 2, "%n%s%n");
373 /* When the format string is writable and contains %n,
374 with -D_FORTIFY_SOURCE=2 it causes __chk_fail. */
376 if (sprintf (buf
, buf2
, str2
, &n1
, str2
, &n1
) != 2)
381 if (snprintf (buf
, 3, buf2
, str2
, &n1
, str2
, &n1
) != 2)
385 /* But if there is no %n, even writable format string
388 if (sprintf (buf
, buf2
+ 4, str2
) != 1)
391 /* Constant literals passed directly are always ok
392 (even with warnings about possible bugs from GCC). */
393 if (printf ("%s%n%s%n", str4
, &n1
, str5
, &n2
) != 14
394 || n1
!= 7 || n2
!= 14)
397 /* In this case the format string is not known at compile time,
398 but resides in read-only memory, so is ok. */
399 if (printf (str3
, str4
, &n1
, str5
, &n2
) != 14
400 || n1
!= 7 || n2
!= 14)
403 strcpy (buf2
+ 2, "%n%s%n");
404 /* When the format string is writable and contains %n,
405 with -D_FORTIFY_SOURCE=2 it causes __chk_fail. */
407 if (printf (buf2
, str4
, &n1
, str5
, &n1
) != 14)
411 /* But if there is no %n, even writable format string
414 if (printf (buf2
+ 4, str5
) != 7)
419 /* Constant literals passed directly are always ok
420 (even with warnings about possible bugs from GCC). */
421 if (fprintf (fp
, "%s%n%s%n", str4
, &n1
, str5
, &n2
) != 14
422 || n1
!= 7 || n2
!= 14)
425 /* In this case the format string is not known at compile time,
426 but resides in read-only memory, so is ok. */
427 if (fprintf (fp
, str3
, str4
, &n1
, str5
, &n2
) != 14
428 || n1
!= 7 || n2
!= 14)
431 strcpy (buf2
+ 2, "%n%s%n");
432 /* When the format string is writable and contains %n,
433 with -D_FORTIFY_SOURCE=2 it causes __chk_fail. */
435 if (fprintf (fp
, buf2
, str4
, &n1
, str5
, &n1
) != 14)
439 /* But if there is no %n, even writable format string
442 if (fprintf (fp
, buf2
+ 4, str5
) != 7)
445 if (freopen (temp_filename
, "r", stdin
) == NULL
)
447 puts ("could not open temporary file");
451 if (gets (buf
) != buf
|| memcmp (buf
, "abcdefgh", 9))
453 if (gets (buf
) != buf
|| memcmp (buf
, "ABCDEFGHI", 10))
456 #if __USE_FORTIFY_LEVEL >= 1
458 if (gets (buf
) != buf
)
465 if (fgets (buf
, sizeof (buf
), stdin
) != buf
466 || memcmp (buf
, "abcdefgh\n", 10))
468 if (fgets (buf
, sizeof (buf
), stdin
) != buf
|| memcmp (buf
, "ABCDEFGHI", 10))
473 if (fgets (buf
, l0
+ sizeof (buf
), stdin
) != buf
474 || memcmp (buf
, "abcdefgh\n", 10))
477 #if __USE_FORTIFY_LEVEL >= 1
479 if (fgets (buf
, sizeof (buf
) + 1, stdin
) != buf
)
484 if (fgets (buf
, l0
+ sizeof (buf
) + 1, stdin
) != buf
)
491 if (fgets_unlocked (buf
, sizeof (buf
), stdin
) != buf
492 || memcmp (buf
, "abcdefgh\n", 10))
494 if (fgets_unlocked (buf
, sizeof (buf
), stdin
) != buf
495 || memcmp (buf
, "ABCDEFGHI", 10))
500 if (fgets_unlocked (buf
, l0
+ sizeof (buf
), stdin
) != buf
501 || memcmp (buf
, "abcdefgh\n", 10))
504 #if __USE_FORTIFY_LEVEL >= 1
506 if (fgets_unlocked (buf
, sizeof (buf
) + 1, stdin
) != buf
)
511 if (fgets_unlocked (buf
, l0
+ sizeof (buf
) + 1, stdin
) != buf
)
516 lseek (fileno (stdin
), 0, SEEK_SET
);
518 if (read (fileno (stdin
), buf
, sizeof (buf
) - 1) != sizeof (buf
) - 1
519 || memcmp (buf
, "abcdefgh\n", 9))
521 if (read (fileno (stdin
), buf
, sizeof (buf
) - 1) != sizeof (buf
) - 1
522 || memcmp (buf
, "ABCDEFGHI", 9))
525 lseek (fileno (stdin
), 0, SEEK_SET
);
527 if (read (fileno (stdin
), buf
, l0
+ sizeof (buf
) - 1) != sizeof (buf
) - 1
528 || memcmp (buf
, "abcdefgh\n", 9))
531 #if __USE_FORTIFY_LEVEL >= 1
533 if (read (fileno (stdin
), buf
, sizeof (buf
) + 1) != sizeof (buf
) + 1)
538 if (pread (fileno (stdin
), buf
, sizeof (buf
) - 1, sizeof (buf
) - 2)
540 || memcmp (buf
, "\nABCDEFGH", 9))
542 if (pread (fileno (stdin
), buf
, sizeof (buf
) - 1, 0) != sizeof (buf
) - 1
543 || memcmp (buf
, "abcdefgh\n", 9))
545 if (pread (fileno (stdin
), buf
, l0
+ sizeof (buf
) - 1, sizeof (buf
) - 3)
547 || memcmp (buf
, "h\nABCDEFG", 9))
550 #if __USE_FORTIFY_LEVEL >= 1
552 if (pread (fileno (stdin
), buf
, sizeof (buf
) + 1, 2 * sizeof (buf
))
558 if (pread64 (fileno (stdin
), buf
, sizeof (buf
) - 1, sizeof (buf
) - 2)
560 || memcmp (buf
, "\nABCDEFGH", 9))
562 if (pread64 (fileno (stdin
), buf
, sizeof (buf
) - 1, 0) != sizeof (buf
) - 1
563 || memcmp (buf
, "abcdefgh\n", 9))
565 if (pread64 (fileno (stdin
), buf
, l0
+ sizeof (buf
) - 1, sizeof (buf
) - 3)
567 || memcmp (buf
, "h\nABCDEFG", 9))
570 #if __USE_FORTIFY_LEVEL >= 1
572 if (pread64 (fileno (stdin
), buf
, sizeof (buf
) + 1, 2 * sizeof (buf
))
578 if (freopen (temp_filename
, "r", stdin
) == NULL
)
580 puts ("could not open temporary file");
584 if (fseek (stdin
, 9 + 10 + 11, SEEK_SET
))
586 puts ("could not seek in test file");
590 #if __USE_FORTIFY_LEVEL >= 1
592 if (gets (buf
) != buf
)
597 /* Check whether missing N$ formats are detected. */
599 printf ("%3$d\n", 1, 2, 3, 4);
603 fprintf (stdout
, "%3$d\n", 1, 2, 3, 4);
607 sprintf (buf
, "%3$d\n", 1, 2, 3, 4);
611 snprintf (buf
, sizeof (buf
), "%3$d\n", 1, 2, 3, 4);
615 if (socketpair (PF_UNIX
, SOCK_STREAM
, 0, sp
))
619 const char *sendstr
= "abcdefgh\nABCDEFGH\n0123456789\n";
620 if (send (sp
[0], sendstr
, strlen (sendstr
), 0) != strlen (sendstr
))
624 if (recv (sp
[1], recvbuf
, sizeof recvbuf
, MSG_PEEK
)
626 || memcmp (recvbuf
, sendstr
, sizeof recvbuf
) != 0)
629 if (recv (sp
[1], recvbuf
+ 6, l0
+ sizeof recvbuf
- 7, MSG_PEEK
)
630 != sizeof recvbuf
- 7
631 || memcmp (recvbuf
+ 6, sendstr
, sizeof recvbuf
- 7) != 0)
634 #if __USE_FORTIFY_LEVEL >= 1
636 if (recv (sp
[1], recvbuf
+ 1, sizeof recvbuf
, MSG_PEEK
)
642 if (recv (sp
[1], recvbuf
+ 4, l0
+ sizeof recvbuf
- 3, MSG_PEEK
)
643 != sizeof recvbuf
- 3)
649 struct sockaddr_un sa_un
;
652 if (recvfrom (sp
[1], recvbuf
, sizeof recvbuf
, MSG_PEEK
, &sa_un
, &sl
)
654 || memcmp (recvbuf
, sendstr
, sizeof recvbuf
) != 0)
658 if (recvfrom (sp
[1], recvbuf
+ 6, l0
+ sizeof recvbuf
- 7, MSG_PEEK
,
659 &sa_un
, &sl
) != sizeof recvbuf
- 7
660 || memcmp (recvbuf
+ 6, sendstr
, sizeof recvbuf
- 7) != 0)
663 #if __USE_FORTIFY_LEVEL >= 1
666 if (recvfrom (sp
[1], recvbuf
+ 1, sizeof recvbuf
, MSG_PEEK
, &sa_un
, &sl
)
673 if (recvfrom (sp
[1], recvbuf
+ 4, l0
+ sizeof recvbuf
- 3, MSG_PEEK
,
674 &sa_un
, &sl
) != sizeof recvbuf
- 3)
683 char fname
[] = "/tmp/tst-chk1-dir-XXXXXX\0foo";
684 char *enddir
= strchr (fname
, '\0');
685 if (mkdtemp (fname
) == NULL
)
687 printf ("mkdtemp failed: %m\n");
691 if (symlink ("bar", fname
) != 0)
695 if (readlink (fname
, readlinkbuf
, 4) != 3
696 || memcmp (readlinkbuf
, "bar", 3) != 0)
698 if (readlink (fname
, readlinkbuf
+ 1, l0
+ 3) != 3
699 || memcmp (readlinkbuf
, "bbar", 4) != 0)
702 #if __USE_FORTIFY_LEVEL >= 1
704 if (readlink (fname
, readlinkbuf
+ 2, l0
+ 3) != 3)
709 if (readlink (fname
, readlinkbuf
+ 3, 4) != 3)
714 char *cwd1
= getcwd (NULL
, 0);
718 char *cwd2
= getcwd (NULL
, 250);
724 if (strcmp (cwd1
, cwd2
) != 0)
731 char *cwd3
= getcwd (NULL
, 0);
734 if (strcmp (fname
, cwd3
) != 0)
735 printf ("getcwd after chdir is '%s' != '%s',"
736 "get{c,}wd tests skipped\n", cwd3
, fname
);
739 char getcwdbuf
[sizeof fname
- 3];
741 char *cwd4
= getcwd (getcwdbuf
, sizeof getcwdbuf
);
742 if (cwd4
!= getcwdbuf
743 || strcmp (getcwdbuf
, fname
) != 0)
746 cwd4
= getcwd (getcwdbuf
+ 1, l0
+ sizeof getcwdbuf
- 1);
747 if (cwd4
!= getcwdbuf
+ 1
748 || getcwdbuf
[0] != fname
[0]
749 || strcmp (getcwdbuf
+ 1, fname
) != 0)
752 #if __USE_FORTIFY_LEVEL >= 1
754 if (getcwd (getcwdbuf
+ 2, l0
+ sizeof getcwdbuf
)
760 if (getcwd (getcwdbuf
+ 2, sizeof getcwdbuf
)
766 if (getwd (getcwdbuf
) != getcwdbuf
767 || strcmp (getcwdbuf
, fname
) != 0)
770 if (getwd (getcwdbuf
+ 1) != getcwdbuf
+ 1
771 || strcmp (getcwdbuf
+ 1, fname
) != 0)
774 #if 0 && __USE_FORTIFY_LEVEL >= 1
776 if (getwd (getcwdbuf
+ 2) != getcwdbuf
+ 2)
782 if (chdir (cwd1
) != 0)
790 if (unlink (fname
) != 0)
794 if (rmdir (fname
) != 0)