debug: Synchronize feature guards in fortified functions [BZ #28746]

Some functions (e.g. stpcpy, pread64, etc.) had moved to POSIX in the
main headers as they got incorporated into the standard, but their
fortified variants remained under __USE_GNU.  As a result, these
functions did not get fortified when _GNU_SOURCE was not defined.

Add test wrappers that check all functions tested in tst-chk0 at all
levels with _GNU_SOURCE undefined and then use the failures to (1)
exclude checks for _GNU_SOURCE functions in these tests and (2) Fix
feature macro guards in the fortified function headers so that they're
the same as the ones in the main headers.

This fixes BZ #28746.

Signed-off-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
Reviewed-by: Adhemerval Zanella  <adhemerval.zanella@linaro.org>
(cherry picked from commit fcfc908681)
This commit is contained in:
Siddhesh Poyarekar 2022-01-12 23:34:48 +05:30
parent f8c2f620f1
commit 224d8c1890
6 changed files with 59 additions and 16 deletions

View File

@ -132,6 +132,12 @@ define cflags-lfs
CFLAGS-tst-fortify-$(1)-lfs-$(2).$(1) += -D_FILE_OFFSET_BITS=64 CFLAGS-tst-fortify-$(1)-lfs-$(2).$(1) += -D_FILE_OFFSET_BITS=64
endef endef
define cflags-nongnu
CFLAGS-tst-fortify-$(1)-nongnu-$(2).$(1) += -D_LARGEFILE64_SOURCE=1
endef
src-chk-nongnu = \#undef _GNU_SOURCE
# We know these tests have problems with format strings, this is what # We know these tests have problems with format strings, this is what
# we are testing. Disable that warning. They are also testing # we are testing. Disable that warning. They are also testing
# deprecated functions (notably gets) so disable that warning as well. # deprecated functions (notably gets) so disable that warning as well.
@ -145,13 +151,13 @@ CFLAGS-tst-fortify-$(1)-$(2)-$(3).$(1) += -D_FORTIFY_SOURCE=$(3) -Wno-format \
$(eval $(call cflags-$(2),$(1),$(3))) $(eval $(call cflags-$(2),$(1),$(3)))
$(objpfx)tst-fortify-$(1)-$(2)-$(3).$(1): tst-fortify.c Makefile $(objpfx)tst-fortify-$(1)-$(2)-$(3).$(1): tst-fortify.c Makefile
( echo "/* Autogenerated from Makefile. */"; \ ( echo "/* Autogenerated from Makefile. */"; \
echo ""; \ echo "$(src-chk-$(2))"; \
echo "#include \"tst-fortify.c\"" ) > $$@.tmp echo "#include \"tst-fortify.c\"" ) > $$@.tmp
mv $$@.tmp $$@ mv $$@.tmp $$@
endef endef
chk-extensions = c cc chk-extensions = c cc
chk-types = default lfs chk-types = default lfs nongnu
chk-levels = 1 2 3 chk-levels = 1 2 3
$(foreach e,$(chk-extensions), \ $(foreach e,$(chk-extensions), \

View File

@ -1,4 +1,5 @@
/* Copyright (C) 2004-2021 Free Software Foundation, Inc. /* Copyright (C) 2004-2022 Free Software Foundation, Inc.
Copyright The GNU Toolchain Authors.
This file is part of the GNU C Library. This file is part of the GNU C Library.
Contributed by Jakub Jelinek <jakub@redhat.com>, 2004. Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
@ -37,6 +38,17 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#ifndef _GNU_SOURCE
# define MEMPCPY memcpy
# define WMEMPCPY wmemcpy
# define MEMPCPY_RET(x) 0
# define WMEMPCPY_RET(x) 0
#else
# define MEMPCPY mempcpy
# define WMEMPCPY wmempcpy
# define MEMPCPY_RET(x) __builtin_strlen (x)
# define WMEMPCPY_RET(x) wcslen (x)
#endif
#define obstack_chunk_alloc malloc #define obstack_chunk_alloc malloc
#define obstack_chunk_free free #define obstack_chunk_free free
@ -163,7 +175,7 @@ do_test (void)
if (memcmp (buf, "aabcdefghi", 10)) if (memcmp (buf, "aabcdefghi", 10))
FAIL (); FAIL ();
if (mempcpy (buf + 5, "abcde", 5) != buf + 10 if (MEMPCPY (buf + 5, "abcde", 5) != buf + 5 + MEMPCPY_RET ("abcde")
|| memcmp (buf, "aabcdabcde", 10)) || memcmp (buf, "aabcdabcde", 10))
FAIL (); FAIL ();
@ -208,7 +220,7 @@ do_test (void)
if (memcmp (buf, "aabcdefghi", 10)) if (memcmp (buf, "aabcdefghi", 10))
FAIL (); FAIL ();
if (mempcpy (buf + 5, "abcde", l0 + 5) != buf + 10 if (MEMPCPY (buf + 5, "abcde", l0 + 5) != buf + 5 + MEMPCPY_RET ("abcde")
|| memcmp (buf, "aabcdabcde", 10)) || memcmp (buf, "aabcdabcde", 10))
FAIL (); FAIL ();
@ -267,7 +279,8 @@ do_test (void)
if (memcmp (a.buf1, "aabcdefghi", 10)) if (memcmp (a.buf1, "aabcdefghi", 10))
FAIL (); FAIL ();
if (mempcpy (a.buf1 + 5, "abcde", l0 + 5) != a.buf1 + 10 if (MEMPCPY (a.buf1 + 5, "abcde", l0 + 5)
!= a.buf1 + 5 + MEMPCPY_RET ("abcde")
|| memcmp (a.buf1, "aabcdabcde", 10)) || memcmp (a.buf1, "aabcdabcde", 10))
FAIL (); FAIL ();
@ -348,6 +361,7 @@ do_test (void)
bcopy (buf + 1, buf + 2, l0 + 9); bcopy (buf + 1, buf + 2, l0 + 9);
CHK_FAIL_END CHK_FAIL_END
#ifdef _GNU_SOURCE
CHK_FAIL_START CHK_FAIL_START
p = (char *) mempcpy (buf + 6, "abcde", 5); p = (char *) mempcpy (buf + 6, "abcde", 5);
CHK_FAIL_END CHK_FAIL_END
@ -355,6 +369,7 @@ do_test (void)
CHK_FAIL_START CHK_FAIL_START
p = (char *) mempcpy (buf + 6, "abcde", l0 + 5); p = (char *) mempcpy (buf + 6, "abcde", l0 + 5);
CHK_FAIL_END CHK_FAIL_END
#endif
CHK_FAIL_START CHK_FAIL_START
memset (buf + 9, 'j', 2); memset (buf + 9, 'j', 2);
@ -465,6 +480,7 @@ do_test (void)
bcopy (a.buf1 + 1, a.buf1 + 2, l0 + 9); bcopy (a.buf1 + 1, a.buf1 + 2, l0 + 9);
CHK_FAIL_END CHK_FAIL_END
#ifdef _GNU_SOURCE
CHK_FAIL_START CHK_FAIL_START
p = (char *) mempcpy (a.buf1 + 6, "abcde", 5); p = (char *) mempcpy (a.buf1 + 6, "abcde", 5);
CHK_FAIL_END CHK_FAIL_END
@ -472,6 +488,7 @@ do_test (void)
CHK_FAIL_START CHK_FAIL_START
p = (char *) mempcpy (a.buf1 + 6, "abcde", l0 + 5); p = (char *) mempcpy (a.buf1 + 6, "abcde", l0 + 5);
CHK_FAIL_END CHK_FAIL_END
#endif
CHK_FAIL_START CHK_FAIL_START
memset (a.buf1 + 9, 'j', 2); memset (a.buf1 + 9, 'j', 2);
@ -551,7 +568,7 @@ do_test (void)
if (wmemcmp (wbuf, L"aabcdefghi", 10)) if (wmemcmp (wbuf, L"aabcdefghi", 10))
FAIL (); FAIL ();
if (wmempcpy (wbuf + 5, L"abcde", 5) != wbuf + 10 if (WMEMPCPY (wbuf + 5, L"abcde", 5) != wbuf + 5 + WMEMPCPY_RET (L"abcde")
|| wmemcmp (wbuf, L"aabcdabcde", 10)) || wmemcmp (wbuf, L"aabcdabcde", 10))
FAIL (); FAIL ();
@ -584,7 +601,8 @@ do_test (void)
if (wmemcmp (wbuf, L"aabcdefghi", 10)) if (wmemcmp (wbuf, L"aabcdefghi", 10))
FAIL (); FAIL ();
if (wmempcpy (wbuf + 5, L"abcde", l0 + 5) != wbuf + 10 if (WMEMPCPY (wbuf + 5, L"abcde", l0 + 5)
!= wbuf + 5 + WMEMPCPY_RET (L"abcde")
|| wmemcmp (wbuf, L"aabcdabcde", 10)) || wmemcmp (wbuf, L"aabcdabcde", 10))
FAIL (); FAIL ();
@ -626,7 +644,8 @@ do_test (void)
if (wmemcmp (wa.buf1, L"aabcdefghi", 10)) if (wmemcmp (wa.buf1, L"aabcdefghi", 10))
FAIL (); FAIL ();
if (wmempcpy (wa.buf1 + 5, L"abcde", l0 + 5) != wa.buf1 + 10 if (WMEMPCPY (wa.buf1 + 5, L"abcde", l0 + 5)
!= wa.buf1 + 5 + WMEMPCPY_RET (L"abcde")
|| wmemcmp (wa.buf1, L"aabcdabcde", 10)) || wmemcmp (wa.buf1, L"aabcdabcde", 10))
FAIL (); FAIL ();
@ -695,6 +714,7 @@ do_test (void)
wmemmove (wbuf + 2, wbuf + 1, l0 + 9); wmemmove (wbuf + 2, wbuf + 1, l0 + 9);
CHK_FAIL_END CHK_FAIL_END
#ifdef _GNU_SOURCE
CHK_FAIL_START CHK_FAIL_START
wp = wmempcpy (wbuf + 6, L"abcde", 5); wp = wmempcpy (wbuf + 6, L"abcde", 5);
CHK_FAIL_END CHK_FAIL_END
@ -702,6 +722,7 @@ do_test (void)
CHK_FAIL_START CHK_FAIL_START
wp = wmempcpy (wbuf + 6, L"abcde", l0 + 5); wp = wmempcpy (wbuf + 6, L"abcde", l0 + 5);
CHK_FAIL_END CHK_FAIL_END
#endif
CHK_FAIL_START CHK_FAIL_START
wmemset (wbuf + 9, L'j', 2); wmemset (wbuf + 9, L'j', 2);
@ -769,6 +790,7 @@ do_test (void)
wmemmove (wa.buf1 + 2, wa.buf1 + 1, l0 + 9); wmemmove (wa.buf1 + 2, wa.buf1 + 1, l0 + 9);
CHK_FAIL_END CHK_FAIL_END
#ifdef _GNU_SOURCE
CHK_FAIL_START CHK_FAIL_START
wp = wmempcpy (wa.buf1 + 6, L"abcde", 5); wp = wmempcpy (wa.buf1 + 6, L"abcde", 5);
CHK_FAIL_END CHK_FAIL_END
@ -776,6 +798,7 @@ do_test (void)
CHK_FAIL_START CHK_FAIL_START
wp = wmempcpy (wa.buf1 + 6, L"abcde", l0 + 5); wp = wmempcpy (wa.buf1 + 6, L"abcde", l0 + 5);
CHK_FAIL_END CHK_FAIL_END
#endif
CHK_FAIL_START CHK_FAIL_START
wmemset (wa.buf1 + 9, L'j', 2); wmemset (wa.buf1 + 9, L'j', 2);
@ -907,6 +930,7 @@ do_test (void)
if (fprintf (fp, buf2 + 4, str5) != 7) if (fprintf (fp, buf2 + 4, str5) != 7)
FAIL (); FAIL ();
#ifdef _GNU_SOURCE
char *my_ptr = NULL; char *my_ptr = NULL;
strcpy (buf2 + 2, "%n%s%n"); strcpy (buf2 + 2, "%n%s%n");
/* When the format string is writable and contains %n, /* When the format string is writable and contains %n,
@ -936,6 +960,7 @@ do_test (void)
if (obstack_printf (&obs, "%s%n%s%n", str4, &n1, str5, &n1) != 14) if (obstack_printf (&obs, "%s%n%s%n", str4, &n1, str5, &n1) != 14)
FAIL (); FAIL ();
obstack_free (&obs, NULL); obstack_free (&obs, NULL);
#endif
if (freopen (temp_filename, "r", stdin) == NULL) if (freopen (temp_filename, "r", stdin) == NULL)
{ {
@ -983,6 +1008,7 @@ do_test (void)
rewind (stdin); rewind (stdin);
#ifdef _GNU_SOURCE
if (fgets_unlocked (buf, buf_size, stdin) != buf if (fgets_unlocked (buf, buf_size, stdin) != buf
|| memcmp (buf, "abcdefgh\n", 10)) || memcmp (buf, "abcdefgh\n", 10))
FAIL (); FAIL ();
@ -1009,6 +1035,7 @@ do_test (void)
#endif #endif
rewind (stdin); rewind (stdin);
#endif
if (fread (buf, 1, buf_size, stdin) != buf_size if (fread (buf, 1, buf_size, stdin) != buf_size
|| memcmp (buf, "abcdefgh\nA", 10)) || memcmp (buf, "abcdefgh\nA", 10))
@ -1579,7 +1606,10 @@ do_test (void)
ret = 1; ret = 1;
} }
int fd = posix_openpt (O_RDWR); int fd;
#ifdef _GNU_SOURCE
fd = posix_openpt (O_RDWR);
if (fd != -1) if (fd != -1)
{ {
char enough[1000]; char enough[1000];
@ -1595,6 +1625,7 @@ do_test (void)
#endif #endif
close (fd); close (fd);
} }
#endif
#if PATH_MAX > 0 #if PATH_MAX > 0
confstr (_CS_GNU_LIBC_VERSION, largebuf, sizeof (largebuf)); confstr (_CS_GNU_LIBC_VERSION, largebuf, sizeof (largebuf));
@ -1712,6 +1743,7 @@ do_test (void)
poll (fds, l0 + 2, 0); poll (fds, l0 + 2, 0);
CHK_FAIL_END CHK_FAIL_END
#endif #endif
#ifdef _GNU_SOURCE
ppoll (fds, 1, NULL, NULL); ppoll (fds, 1, NULL, NULL);
# if __USE_FORTIFY_LEVEL >= 1 # if __USE_FORTIFY_LEVEL >= 1
CHK_FAIL_START CHK_FAIL_START
@ -1721,6 +1753,7 @@ do_test (void)
CHK_FAIL_START CHK_FAIL_START
ppoll (fds, l0 + 2, NULL, NULL); ppoll (fds, l0 + 2, NULL, NULL);
CHK_FAIL_END CHK_FAIL_END
# endif
#endif #endif
return ret; return ret;

View File

@ -40,7 +40,7 @@ read (int __fd, void *__buf, size_t __nbytes)
__fd, __buf, __nbytes); __fd, __buf, __nbytes);
} }
#ifdef __USE_UNIX98 #if defined __USE_UNIX98 || defined __USE_XOPEN2K8
extern ssize_t __pread_chk (int __fd, void *__buf, size_t __nbytes, extern ssize_t __pread_chk (int __fd, void *__buf, size_t __nbytes,
__off_t __offset, size_t __bufsize) __off_t __offset, size_t __bufsize)
__wur __attr_access ((__write_only__, 2, 3)); __wur __attr_access ((__write_only__, 2, 3));

View File

@ -79,7 +79,7 @@ __NTH (strcpy (char *__restrict __dest, const char *__restrict __src))
return __builtin___strcpy_chk (__dest, __src, __glibc_objsize (__dest)); return __builtin___strcpy_chk (__dest, __src, __glibc_objsize (__dest));
} }
#ifdef __USE_GNU #ifdef __USE_XOPEN2K8
__fortify_function char * __fortify_function char *
__NTH (stpcpy (char *__restrict __dest, const char *__restrict __src)) __NTH (stpcpy (char *__restrict __dest, const char *__restrict __src))
{ {
@ -96,6 +96,7 @@ __NTH (strncpy (char *__restrict __dest, const char *__restrict __src,
__glibc_objsize (__dest)); __glibc_objsize (__dest));
} }
#ifdef __USE_XOPEN2K8
# if __GNUC_PREREQ (4, 7) || __glibc_clang_prereq (2, 6) # if __GNUC_PREREQ (4, 7) || __glibc_clang_prereq (2, 6)
__fortify_function char * __fortify_function char *
__NTH (stpncpy (char *__dest, const char *__src, size_t __n)) __NTH (stpncpy (char *__dest, const char *__src, size_t __n))
@ -120,6 +121,7 @@ __NTH (stpncpy (char *__dest, const char *__src, size_t __n))
return __stpncpy_alias (__dest, __src, __n); return __stpncpy_alias (__dest, __src, __n);
} }
# endif # endif
#endif
__fortify_function char * __fortify_function char *

View File

@ -28,7 +28,9 @@ __BEGIN_DECLS
terminate the process on error. */ terminate the process on error. */
void xraise (int sig); void xraise (int sig);
#ifdef _GNU_SOURCE
sighandler_t xsignal (int sig, sighandler_t handler); sighandler_t xsignal (int sig, sighandler_t handler);
#endif
void xsigaction (int sig, const struct sigaction *newact, void xsigaction (int sig, const struct sigaction *newact,
struct sigaction *oldact); struct sigaction *oldact);

View File

@ -457,7 +457,7 @@ __NTH (wcsrtombs (char *__restrict __dst, const wchar_t **__restrict __src,
} }
#ifdef __USE_GNU #ifdef __USE_XOPEN2K8
extern size_t __mbsnrtowcs_chk (wchar_t *__restrict __dst, extern size_t __mbsnrtowcs_chk (wchar_t *__restrict __dst,
const char **__restrict __src, size_t __nmc, const char **__restrict __src, size_t __nmc,
size_t __len, mbstate_t *__restrict __ps, size_t __len, mbstate_t *__restrict __ps,