a41fe4
commit fcfc9086815bf0d277ad47a90ee3fda4c37acca8
a41fe4
Author: Siddhesh Poyarekar <siddhesh@sourceware.org>
a41fe4
Date:   Wed Jan 12 23:34:48 2022 +0530
a41fe4
a41fe4
    debug: Synchronize feature guards in fortified functions [BZ #28746]
a41fe4
    
a41fe4
    Some functions (e.g. stpcpy, pread64, etc.) had moved to POSIX in the
a41fe4
    main headers as they got incorporated into the standard, but their
a41fe4
    fortified variants remained under __USE_GNU.  As a result, these
a41fe4
    functions did not get fortified when _GNU_SOURCE was not defined.
a41fe4
    
a41fe4
    Add test wrappers that check all functions tested in tst-chk0 at all
a41fe4
    levels with _GNU_SOURCE undefined and then use the failures to (1)
a41fe4
    exclude checks for _GNU_SOURCE functions in these tests and (2) Fix
a41fe4
    feature macro guards in the fortified function headers so that they're
a41fe4
    the same as the ones in the main headers.
a41fe4
    
a41fe4
    This fixes BZ #28746.
a41fe4
    
a41fe4
    Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
a41fe4
    Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
a41fe4
a41fe4
# Conflicts:
a41fe4
#	debug/tst-fortify.c
a41fe4
a41fe4
diff --git a/debug/Makefile b/debug/Makefile
a41fe4
index c92fd23dda1a7279..b0f0b7beb6d5cef5 100644
a41fe4
--- a/debug/Makefile
a41fe4
+++ b/debug/Makefile
a41fe4
@@ -132,6 +132,12 @@ define cflags-lfs
a41fe4
 CFLAGS-tst-fortify-$(1)-lfs-$(2).$(1) += -D_FILE_OFFSET_BITS=64
a41fe4
 endef
a41fe4
 
a41fe4
+define cflags-nongnu
a41fe4
+CFLAGS-tst-fortify-$(1)-nongnu-$(2).$(1) += -D_LARGEFILE64_SOURCE=1
a41fe4
+endef
a41fe4
+
a41fe4
+src-chk-nongnu = \#undef _GNU_SOURCE
a41fe4
+
a41fe4
 # We know these tests have problems with format strings, this is what
a41fe4
 # we are testing.  Disable that warning.  They are also testing
a41fe4
 # deprecated functions (notably gets) so disable that warning as well.
a41fe4
@@ -145,13 +151,13 @@ CFLAGS-tst-fortify-$(1)-$(2)-$(3).$(1) += -D_FORTIFY_SOURCE=$(3) -Wno-format \
a41fe4
 $(eval $(call cflags-$(2),$(1),$(3)))
a41fe4
 $(objpfx)tst-fortify-$(1)-$(2)-$(3).$(1): tst-fortify.c Makefile
a41fe4
 	( echo "/* Autogenerated from Makefile.  */"; \
a41fe4
-	  echo ""; \
a41fe4
+	  echo "$(src-chk-$(2))"; \
a41fe4
 	  echo "#include \"tst-fortify.c\"" ) > $$@.tmp
a41fe4
 	mv $$@.tmp $$@
a41fe4
 endef
a41fe4
 
a41fe4
 chk-extensions = c cc
a41fe4
-chk-types = default lfs
a41fe4
+chk-types = default lfs nongnu
a41fe4
 chk-levels = 1 2 3
a41fe4
 
a41fe4
 $(foreach e,$(chk-extensions), \
a41fe4
diff --git a/debug/tst-fortify.c b/debug/tst-fortify.c
a41fe4
index 5e76081255316a93..1668294e48b5c63c 100644
a41fe4
--- a/debug/tst-fortify.c
a41fe4
+++ b/debug/tst-fortify.c
a41fe4
@@ -1,4 +1,5 @@
a41fe4
-/* Copyright (C) 2004-2018 Free Software Foundation, Inc.
a41fe4
+/* Copyright (C) 2004-2022 Free Software Foundation, Inc.
a41fe4
+   Copyright The GNU Toolchain Authors.
a41fe4
    This file is part of the GNU C Library.
a41fe4
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
a41fe4
 
a41fe4
@@ -37,6 +38,17 @@
a41fe4
 #include <sys/socket.h>
a41fe4
 #include <sys/un.h>
a41fe4
 
a41fe4
+#ifndef _GNU_SOURCE
a41fe4
+# define MEMPCPY memcpy
a41fe4
+# define WMEMPCPY wmemcpy
a41fe4
+# define MEMPCPY_RET(x) 0
a41fe4
+# define WMEMPCPY_RET(x) 0
a41fe4
+#else
a41fe4
+# define MEMPCPY mempcpy
a41fe4
+# define WMEMPCPY wmempcpy
a41fe4
+# define MEMPCPY_RET(x) __builtin_strlen (x)
a41fe4
+# define WMEMPCPY_RET(x) wcslen (x)
a41fe4
+#endif
a41fe4
 
a41fe4
 #define obstack_chunk_alloc malloc
a41fe4
 #define obstack_chunk_free free
a41fe4
@@ -163,7 +175,7 @@ do_test (void)
a41fe4
   if (memcmp (buf, "aabcdefghi", 10))
a41fe4
     FAIL ();
a41fe4
 
a41fe4
-  if (mempcpy (buf + 5, "abcde", 5) != buf + 10
a41fe4
+  if (MEMPCPY (buf + 5, "abcde", 5) != buf + 5 + MEMPCPY_RET ("abcde")
a41fe4
       || memcmp (buf, "aabcdabcde", 10))
a41fe4
     FAIL ();
a41fe4
 
a41fe4
@@ -208,7 +220,7 @@ do_test (void)
a41fe4
   if (memcmp (buf, "aabcdefghi", 10))
a41fe4
     FAIL ();
a41fe4
 
a41fe4
-  if (mempcpy (buf + 5, "abcde", l0 + 5) != buf + 10
a41fe4
+  if (MEMPCPY (buf + 5, "abcde", l0 + 5) != buf + 5 + MEMPCPY_RET ("abcde")
a41fe4
       || memcmp (buf, "aabcdabcde", 10))
a41fe4
     FAIL ();
a41fe4
 
a41fe4
@@ -267,7 +279,8 @@ do_test (void)
a41fe4
   if (memcmp (a.buf1, "aabcdefghi", 10))
a41fe4
     FAIL ();
a41fe4
 
a41fe4
-  if (mempcpy (a.buf1 + 5, "abcde", l0 + 5) != a.buf1 + 10
a41fe4
+  if (MEMPCPY (a.buf1 + 5, "abcde", l0 + 5)
a41fe4
+      != a.buf1 + 5 + MEMPCPY_RET ("abcde")
a41fe4
       || memcmp (a.buf1, "aabcdabcde", 10))
a41fe4
     FAIL ();
a41fe4
 
a41fe4
@@ -348,6 +361,7 @@ do_test (void)
a41fe4
   bcopy (buf + 1, buf + 2, l0 + 9);
a41fe4
   CHK_FAIL_END
a41fe4
 
a41fe4
+#ifdef _GNU_SOURCE
a41fe4
   CHK_FAIL_START
a41fe4
   p = (char *) mempcpy (buf + 6, "abcde", 5);
a41fe4
   CHK_FAIL_END
a41fe4
@@ -355,6 +369,7 @@ do_test (void)
a41fe4
   CHK_FAIL_START
a41fe4
   p = (char *) mempcpy (buf + 6, "abcde", l0 + 5);
a41fe4
   CHK_FAIL_END
a41fe4
+#endif
a41fe4
 
a41fe4
   CHK_FAIL_START
a41fe4
   memset (buf + 9, 'j', 2);
a41fe4
@@ -465,6 +480,7 @@ do_test (void)
a41fe4
   bcopy (a.buf1 + 1, a.buf1 + 2, l0 + 9);
a41fe4
   CHK_FAIL_END
a41fe4
 
a41fe4
+#ifdef _GNU_SOURCE
a41fe4
   CHK_FAIL_START
a41fe4
   p = (char *) mempcpy (a.buf1 + 6, "abcde", 5);
a41fe4
   CHK_FAIL_END
a41fe4
@@ -472,6 +488,7 @@ do_test (void)
a41fe4
   CHK_FAIL_START
a41fe4
   p = (char *) mempcpy (a.buf1 + 6, "abcde", l0 + 5);
a41fe4
   CHK_FAIL_END
a41fe4
+#endif
a41fe4
 
a41fe4
   CHK_FAIL_START
a41fe4
   memset (a.buf1 + 9, 'j', 2);
a41fe4
@@ -551,7 +568,7 @@ do_test (void)
a41fe4
   if (wmemcmp (wbuf, L"aabcdefghi", 10))
a41fe4
     FAIL ();
a41fe4
 
a41fe4
-  if (wmempcpy (wbuf + 5, L"abcde", 5) != wbuf + 10
a41fe4
+  if (WMEMPCPY (wbuf + 5, L"abcde", 5) != wbuf + 5 + WMEMPCPY_RET (L"abcde")
a41fe4
       || wmemcmp (wbuf, L"aabcdabcde", 10))
a41fe4
     FAIL ();
a41fe4
 
a41fe4
@@ -584,7 +601,8 @@ do_test (void)
a41fe4
   if (wmemcmp (wbuf, L"aabcdefghi", 10))
a41fe4
     FAIL ();
a41fe4
 
a41fe4
-  if (wmempcpy (wbuf + 5, L"abcde", l0 + 5) != wbuf + 10
a41fe4
+  if (WMEMPCPY (wbuf + 5, L"abcde", l0 + 5)
a41fe4
+      != wbuf + 5 + WMEMPCPY_RET (L"abcde")
a41fe4
       || wmemcmp (wbuf, L"aabcdabcde", 10))
a41fe4
     FAIL ();
a41fe4
 
a41fe4
@@ -626,7 +644,8 @@ do_test (void)
a41fe4
   if (wmemcmp (wa.buf1, L"aabcdefghi", 10))
a41fe4
     FAIL ();
a41fe4
 
a41fe4
-  if (wmempcpy (wa.buf1 + 5, L"abcde", l0 + 5) != wa.buf1 + 10
a41fe4
+  if (WMEMPCPY (wa.buf1 + 5, L"abcde", l0 + 5)
a41fe4
+      != wa.buf1 + 5 + WMEMPCPY_RET (L"abcde")
a41fe4
       || wmemcmp (wa.buf1, L"aabcdabcde", 10))
a41fe4
     FAIL ();
a41fe4
 
a41fe4
@@ -695,6 +714,7 @@ do_test (void)
a41fe4
   wmemmove (wbuf + 2, wbuf + 1, l0 + 9);
a41fe4
   CHK_FAIL_END
a41fe4
 
a41fe4
+#ifdef _GNU_SOURCE
a41fe4
   CHK_FAIL_START
a41fe4
   wp = wmempcpy (wbuf + 6, L"abcde", 5);
a41fe4
   CHK_FAIL_END
a41fe4
@@ -702,6 +722,7 @@ do_test (void)
a41fe4
   CHK_FAIL_START
a41fe4
   wp = wmempcpy (wbuf + 6, L"abcde", l0 + 5);
a41fe4
   CHK_FAIL_END
a41fe4
+#endif
a41fe4
 
a41fe4
   CHK_FAIL_START
a41fe4
   wmemset (wbuf + 9, L'j', 2);
a41fe4
@@ -769,6 +790,7 @@ do_test (void)
a41fe4
   wmemmove (wa.buf1 + 2, wa.buf1 + 1, l0 + 9);
a41fe4
   CHK_FAIL_END
a41fe4
 
a41fe4
+#ifdef _GNU_SOURCE
a41fe4
   CHK_FAIL_START
a41fe4
   wp = wmempcpy (wa.buf1 + 6, L"abcde", 5);
a41fe4
   CHK_FAIL_END
a41fe4
@@ -776,6 +798,7 @@ do_test (void)
a41fe4
   CHK_FAIL_START
a41fe4
   wp = wmempcpy (wa.buf1 + 6, L"abcde", l0 + 5);
a41fe4
   CHK_FAIL_END
a41fe4
+#endif
a41fe4
 
a41fe4
   CHK_FAIL_START
a41fe4
   wmemset (wa.buf1 + 9, L'j', 2);
a41fe4
@@ -907,6 +930,7 @@ do_test (void)
a41fe4
   if (fprintf (fp, buf2 + 4, str5) != 7)
a41fe4
     FAIL ();
a41fe4
 
a41fe4
+#ifdef _GNU_SOURCE
a41fe4
   char *my_ptr = NULL;
a41fe4
   strcpy (buf2 + 2, "%n%s%n");
a41fe4
   /* When the format string is writable and contains %n,
a41fe4
@@ -936,6 +960,7 @@ do_test (void)
a41fe4
   if (obstack_printf (&obs, "%s%n%s%n", str4, &n1, str5, &n1) != 14)
a41fe4
     FAIL ();
a41fe4
   obstack_free (&obs, NULL);
a41fe4
+#endif
a41fe4
 
a41fe4
   if (freopen (temp_filename, "r", stdin) == NULL)
a41fe4
     {
a41fe4
@@ -983,6 +1008,7 @@ do_test (void)
a41fe4
 
a41fe4
   rewind (stdin);
a41fe4
 
a41fe4
+#ifdef _GNU_SOURCE
a41fe4
   if (fgets_unlocked (buf, buf_size, stdin) != buf
a41fe4
       || memcmp (buf, "abcdefgh\n", 10))
a41fe4
     FAIL ();
a41fe4
@@ -1009,6 +1035,7 @@ do_test (void)
a41fe4
 #endif
a41fe4
 
a41fe4
   rewind (stdin);
a41fe4
+#endif
a41fe4
 
a41fe4
   if (fread (buf, 1, buf_size, stdin) != buf_size
a41fe4
       || memcmp (buf, "abcdefgh\nA", 10))
a41fe4
@@ -1579,7 +1606,10 @@ do_test (void)
a41fe4
       ret = 1;
a41fe4
     }
a41fe4
 
a41fe4
-  int fd = posix_openpt (O_RDWR);
a41fe4
+  int fd;
a41fe4
+
a41fe4
+#ifdef _GNU_SOURCE
a41fe4
+  fd = posix_openpt (O_RDWR);
a41fe4
   if (fd != -1)
a41fe4
     {
a41fe4
       char enough[1000];
a41fe4
@@ -1595,6 +1625,7 @@ do_test (void)
a41fe4
 #endif
a41fe4
       close (fd);
a41fe4
     }
a41fe4
+#endif
a41fe4
 
a41fe4
 #if PATH_MAX > 0
a41fe4
   confstr (_CS_GNU_LIBC_VERSION, largebuf, sizeof (largebuf));
a41fe4
@@ -1712,8 +1743,9 @@ do_test (void)
a41fe4
   poll (fds, l0 + 2, 0);
a41fe4
   CHK_FAIL_END
a41fe4
 #endif
a41fe4
+#ifdef _GNU_SOURCE
a41fe4
   ppoll (fds, 1, NULL, NULL);
a41fe4
-#if __USE_FORTIFY_LEVEL >= 1
a41fe4
+# if __USE_FORTIFY_LEVEL >= 1
a41fe4
   CHK_FAIL_START
a41fe4
   ppoll (fds, 2, NULL, NULL);
a41fe4
   CHK_FAIL_END
a41fe4
@@ -1721,6 +1753,7 @@ do_test (void)
a41fe4
   CHK_FAIL_START
a41fe4
   ppoll (fds, l0 + 2, NULL, NULL);
a41fe4
   CHK_FAIL_END
a41fe4
+# endif
a41fe4
 #endif
a41fe4
 
a41fe4
   return ret;
a41fe4
diff --git a/posix/bits/unistd.h b/posix/bits/unistd.h
a41fe4
index a456d1723547db70..ddfaed4dd7574cd2 100644
a41fe4
--- a/posix/bits/unistd.h
a41fe4
+++ b/posix/bits/unistd.h
a41fe4
@@ -38,7 +38,7 @@ read (int __fd, void *__buf, size_t __nbytes)
a41fe4
 			  __fd, __buf, __nbytes);
a41fe4
 }
a41fe4
 
a41fe4
-#ifdef __USE_UNIX98
a41fe4
+#if defined __USE_UNIX98 || defined __USE_XOPEN2K8
a41fe4
 extern ssize_t __pread_chk (int __fd, void *__buf, size_t __nbytes,
a41fe4
 			    __off_t __offset, size_t __bufsize) __wur;
a41fe4
 extern ssize_t __pread64_chk (int __fd, void *__buf, size_t __nbytes,
a41fe4
diff --git a/string/bits/string_fortified.h b/string/bits/string_fortified.h
a41fe4
index 27ec273ec41cd81c..3f86629bf8fc51a2 100644
a41fe4
--- a/string/bits/string_fortified.h
a41fe4
+++ b/string/bits/string_fortified.h
a41fe4
@@ -94,7 +94,7 @@ __NTH (strcpy (char *__restrict __dest, const char *__restrict __src))
a41fe4
   return __builtin___strcpy_chk (__dest, __src, __glibc_objsize (__dest));
a41fe4
 }
a41fe4
 
a41fe4
-#ifdef __USE_GNU
a41fe4
+#ifdef __USE_XOPEN2K8
a41fe4
 __fortify_function char *
a41fe4
 __NTH (stpcpy (char *__restrict __dest, const char *__restrict __src))
a41fe4
 {
a41fe4
@@ -111,14 +111,15 @@ __NTH (strncpy (char *__restrict __dest, const char *__restrict __src,
a41fe4
 				  __glibc_objsize (__dest));
a41fe4
 }
a41fe4
 
a41fe4
-#if __GNUC_PREREQ (4, 7) || __glibc_clang_prereq (2, 6)
a41fe4
+#ifdef __USE_XOPEN2K8
a41fe4
+# if __GNUC_PREREQ (4, 7) || __glibc_clang_prereq (2, 6)
a41fe4
 __fortify_function char *
a41fe4
 __NTH (stpncpy (char *__dest, const char *__src, size_t __n))
a41fe4
 {
a41fe4
   return __builtin___stpncpy_chk (__dest, __src, __n,
a41fe4
 				  __glibc_objsize (__dest));
a41fe4
 }
a41fe4
-#else
a41fe4
+# else
a41fe4
 extern char *__stpncpy_chk (char *__dest, const char *__src, size_t __n,
a41fe4
 			    size_t __destlen) __THROW;
a41fe4
 extern char *__REDIRECT_NTH (__stpncpy_alias, (char *__dest, const char *__src,
a41fe4
@@ -132,6 +133,7 @@ __NTH (stpncpy (char *__dest, const char *__src, size_t __n))
a41fe4
     return __stpncpy_chk (__dest, __src, __n, __bos (__dest));
a41fe4
   return __stpncpy_alias (__dest, __src, __n);
a41fe4
 }
a41fe4
+# endif
a41fe4
 #endif
a41fe4
 
a41fe4
 
a41fe4
diff --git a/support/xsignal.h b/support/xsignal.h
a41fe4
index 9ab8d1bfddf6c598..fae6108a522ae5fe 100644
a41fe4
--- a/support/xsignal.h
a41fe4
+++ b/support/xsignal.h
a41fe4
@@ -28,7 +28,9 @@ __BEGIN_DECLS
a41fe4
    terminate the process on error.  */
a41fe4
 
a41fe4
 void xraise (int sig);
a41fe4
+#ifdef _GNU_SOURCE
a41fe4
 sighandler_t xsignal (int sig, sighandler_t handler);
a41fe4
+#endif
a41fe4
 void xsigaction (int sig, const struct sigaction *newact,
a41fe4
                  struct sigaction *oldact);
a41fe4
 
a41fe4
diff --git a/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h
a41fe4
index f82bba481981e4fb..5c68979e96a504b4 100644
a41fe4
--- a/wcsmbs/bits/wchar2.h
a41fe4
+++ b/wcsmbs/bits/wchar2.h
a41fe4
@@ -457,7 +457,7 @@ __NTH (wcsrtombs (char *__restrict __dst, const wchar_t **__restrict __src,
a41fe4
 }
a41fe4
 
a41fe4
 
a41fe4
-#ifdef __USE_GNU
a41fe4
+#ifdef	__USE_XOPEN2K8
a41fe4
 extern size_t __mbsnrtowcs_chk (wchar_t *__restrict __dst,
a41fe4
 				const char **__restrict __src, size_t __nmc,
a41fe4
 				size_t __len, mbstate_t *__restrict __ps,