diff --git a/SOURCES/build-locale-archive.c b/SOURCES/build-locale-archive.c index 9183972..3cb3b47 100644 --- a/SOURCES/build-locale-archive.c +++ b/SOURCES/build-locale-archive.c @@ -448,7 +448,7 @@ fill_archive (struct locarhandle *tmpl_ah, char fullname[fnamelen + 2 * strlen (d->d_name) + 7]; #ifdef _DIRENT_HAVE_D_TYPE - if (d_type == DT_UNKNOWN) + if (d_type == DT_UNKNOWN || d_type == DT_LNK) #endif { strcpy (stpcpy (stpcpy (fullname, fname), "/"), diff --git a/SOURCES/glibc-rh2033684-1.patch b/SOURCES/glibc-rh2033684-1.patch new file mode 100644 index 0000000..8734628 --- /dev/null +++ b/SOURCES/glibc-rh2033684-1.patch @@ -0,0 +1,27 @@ +commit 2a08b6e8331a611dc29325bfa6e29fecc9a3a46e +Author: Siddhesh Poyarekar +Date: Thu Dec 10 16:47:02 2020 +0530 + + Warn on unsupported fortification levels + + Make the _FORTIFY_SOURCE macro soup in features.h warn about + unsupported fortification levels. For example, it will warn about + _FORTIFY_SOURCE=3 and over with an indication of which level has been + selected. + + Co-authored-by: Paul Eggert + +diff --git a/include/features.h b/include/features.h +index 5bed0a499605a3a2..ea7673ee115bcf0a 100644 +--- a/include/features.h ++++ b/include/features.h +@@ -382,6 +382,9 @@ + # elif !__GNUC_PREREQ (4, 1) + # warning _FORTIFY_SOURCE requires GCC 4.1 or later + # elif _FORTIFY_SOURCE > 1 ++# if _FORTIFY_SOURCE > 2 ++# warning _FORTIFY_SOURCE > 2 is treated like 2 on this platform ++# endif + # define __USE_FORTIFY_LEVEL 2 + # else + # define __USE_FORTIFY_LEVEL 1 diff --git a/SOURCES/glibc-rh2033684-10.patch b/SOURCES/glibc-rh2033684-10.patch new file mode 100644 index 0000000..94b4519 --- /dev/null +++ b/SOURCES/glibc-rh2033684-10.patch @@ -0,0 +1,90 @@ +commit 2bbd07c715275eb6c616988925738a0517180d57 +Author: Siddhesh Poyarekar +Date: Fri Dec 17 18:35:44 2021 +0530 + + fortify: Fix spurious warning with realpath + + The length and object size arguments were swapped around for realpath. + Also add a smoke test so that any changes in this area get caught in + future. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Adhemerval Zanella + +diff --git a/debug/Makefile b/debug/Makefile +index 81361438fc3d2aa9..b43f42ee3851f360 100644 +--- a/debug/Makefile ++++ b/debug/Makefile +@@ -108,6 +108,7 @@ CFLAGS-tst-longjmp_chk2.c += -fexceptions -fasynchronous-unwind-tables + CPPFLAGS-tst-longjmp_chk2.c += -D_FORTIFY_SOURCE=1 + CFLAGS-tst-longjmp_chk3.c += -fexceptions -fasynchronous-unwind-tables + CPPFLAGS-tst-longjmp_chk3.c += -D_FORTIFY_SOURCE=1 ++CPPFLAGS-tst-realpath-chk.c += -D_FORTIFY_SOURCE=2 + + # We know these tests have problems with format strings, this is what + # we are testing. Disable that warning. They are also testing +@@ -155,7 +156,7 @@ tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \ + tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \ + tst-chk4 tst-chk5 tst-chk6 tst-chk7 tst-chk8 tst-lfschk4 tst-lfschk5 \ + tst-lfschk6 tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 \ +- tst-backtrace4 tst-backtrace5 tst-backtrace6 ++ tst-backtrace4 tst-backtrace5 tst-backtrace6 tst-realpath-chk + + ifeq ($(have-ssp),yes) + tests += tst-ssp-1 +diff --git a/debug/tst-realpath-chk.c b/debug/tst-realpath-chk.c +new file mode 100644 +index 0000000000000000..a8fcb327c43fb34d +--- /dev/null ++++ b/debug/tst-realpath-chk.c +@@ -0,0 +1,37 @@ ++/* Smoke test to verify that realpath does not cause spurious warnings. ++ Copyright The GNU Toolchain Authors. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++ ++#include ++#include ++ ++static int ++do_test (void) ++{ ++#ifdef PATH_MAX ++ char buf[PATH_MAX + 1]; ++ char *res = realpath (".", buf); ++ TEST_VERIFY (res == buf); ++#endif ++ ++ return 0; ++} ++ ++#include +diff --git a/stdlib/bits/stdlib.h b/stdlib/bits/stdlib.h +index 7ea364a276497720..81ec9bdb32215e3b 100644 +--- a/stdlib/bits/stdlib.h ++++ b/stdlib/bits/stdlib.h +@@ -42,7 +42,7 @@ __NTH (realpath (const char *__restrict __name, char *__restrict __resolved)) + return __realpath_alias (__name, __resolved); + + #if defined _LIBC_LIMITS_H_ && defined PATH_MAX +- if (__glibc_unsafe_len (sz, sizeof (char), PATH_MAX)) ++ if (__glibc_unsafe_len (PATH_MAX, sizeof (char), sz)) + return __realpath_chk_warn (__name, __resolved, sz); + #endif + return __realpath_chk (__name, __resolved, sz); diff --git a/SOURCES/glibc-rh2033684-11.patch b/SOURCES/glibc-rh2033684-11.patch new file mode 100644 index 0000000..41ce66c --- /dev/null +++ b/SOURCES/glibc-rh2033684-11.patch @@ -0,0 +1,41 @@ +commit 86bf0feb0e3ec8e37872f72499d6ae33406561d7 +Author: Siddhesh Poyarekar +Date: Wed Jan 12 18:46:28 2022 +0530 + + Enable _FORTIFY_SOURCE=3 for gcc 12 and above + + gcc 12 now has support for the __builtin_dynamic_object_size builtin. + Adapt the macro checks to enable _FORTIFY_SOURCE=3 on gcc 12 and above. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Adhemerval Zanella + +diff --git a/include/features.h b/include/features.h +index fe9fe16d034fad1b..2e9ca6ec2f4a0380 100644 +--- a/include/features.h ++++ b/include/features.h +@@ -381,7 +381,9 @@ + # warning _FORTIFY_SOURCE requires compiling with optimization (-O) + # elif !__GNUC_PREREQ (4, 1) + # warning _FORTIFY_SOURCE requires GCC 4.1 or later +-# elif _FORTIFY_SOURCE > 2 && __glibc_clang_prereq (9, 0) ++# elif _FORTIFY_SOURCE > 2 && (__glibc_clang_prereq (9, 0) \ ++ || __GNUC_PREREQ (12, 0)) ++ + # if _FORTIFY_SOURCE > 3 + # warning _FORTIFY_SOURCE > 3 is treated like 3 on this platform + # endif +diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h +index 147339957c4ad490..a17ae0ed87e6163f 100644 +--- a/misc/sys/cdefs.h ++++ b/misc/sys/cdefs.h +@@ -124,7 +124,8 @@ + #define __bos0(ptr) __builtin_object_size (ptr, 0) + + /* Use __builtin_dynamic_object_size at _FORTIFY_SOURCE=3 when available. */ +-#if __USE_FORTIFY_LEVEL == 3 && __glibc_clang_prereq (9, 0) ++#if __USE_FORTIFY_LEVEL == 3 && (__glibc_clang_prereq (9, 0) \ ++ || __GNUC_PREREQ (12, 0)) + # define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0) + # define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1) + #else diff --git a/SOURCES/glibc-rh2033684-12.patch b/SOURCES/glibc-rh2033684-12.patch new file mode 100644 index 0000000..9c9c98f --- /dev/null +++ b/SOURCES/glibc-rh2033684-12.patch @@ -0,0 +1,295 @@ +commit db27f1251b008280a29d540b4f8ab2a38a0d80af +Author: Siddhesh Poyarekar +Date: Wed Jan 12 23:34:23 2022 +0530 + + debug: Autogenerate _FORTIFY_SOURCE tests + + Rename debug/tst-chk1.c to debug/tst-fortify.c and add make hackery to + autogenerate tests with different macros enabled to build and run the + same test with different configurations as well as different + fortification levels. + + The change also ends up expanding the -lfs tests to include + _FORTIFY_SOURCE=3. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Adhemerval Zanella + +# Conflicts: +# debug/Makefile + +diff --git a/Makerules b/Makerules +index 5d6434c74bf9bfe5..05a549eb0f259113 100644 +--- a/Makerules ++++ b/Makerules +@@ -444,6 +444,12 @@ $(objpfx)%$o: $(objpfx)%.c $(before-compile); $$(compile-command.c) + endef + object-suffixes-left := $(all-object-suffixes) + include $(o-iterator) ++ ++define o-iterator-doit ++$(objpfx)%$o: $(objpfx)%.cc $(before-compile); $$(compile-command.cc) ++endef ++object-suffixes-left := $(all-object-suffixes) ++include $(o-iterator) + endif + + # Generate version maps, but wait until sysdep-subdirs is known +diff --git a/debug/Makefile b/debug/Makefile +index b43f42ee3851f360..c92fd23dda1a7279 100644 +--- a/debug/Makefile ++++ b/debug/Makefile +@@ -1,4 +1,5 @@ +-# Copyright (C) 1998-2018 Free Software Foundation, Inc. ++# Copyright (C) 1998-2022 Free Software Foundation, Inc. ++# Copyright The GNU Toolchain Authors. + # This file is part of the GNU C Library. + + # The GNU C Library is free software; you can redistribute it and/or +@@ -110,32 +111,60 @@ CFLAGS-tst-longjmp_chk3.c += -fexceptions -fasynchronous-unwind-tables + CPPFLAGS-tst-longjmp_chk3.c += -D_FORTIFY_SOURCE=1 + CPPFLAGS-tst-realpath-chk.c += -D_FORTIFY_SOURCE=2 + ++# _FORTIFY_SOURCE tests. ++# Auto-generate tests for _FORTIFY_SOURCE for different levels, compilers and ++# preprocessor conditions based on tst-fortify.c. ++# ++# To add a new test condition, define a cflags-$(cond) make variable to set ++# CFLAGS for the file. ++ ++tests-all-chk = tst-fortify ++tests-c-chk = ++tests-cc-chk = ++ ++CFLAGS-tst-fortify.c += -Wno-format -Wno-deprecated-declarations -Wno-error ++ ++# No additional flags for the default tests. ++define cflags-default ++endef ++ ++define cflags-lfs ++CFLAGS-tst-fortify-$(1)-lfs-$(2).$(1) += -D_FILE_OFFSET_BITS=64 ++endef ++ + # We know these tests have problems with format strings, this is what + # we are testing. Disable that warning. They are also testing + # deprecated functions (notably gets) so disable that warning as well. + # And they also generate warnings from warning attributes, which + # cannot be disabled via pragmas, so require -Wno-error to be used. +-CFLAGS-tst-chk1.c += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-chk2.c += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-chk3.c += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-chk4.cc += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-chk5.cc += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-chk6.cc += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-chk7.c += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-chk8.cc += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-lfschk1.c += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-lfschk2.c += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-lfschk3.c += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-lfschk4.cc += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-lfschk5.cc += -Wno-format -Wno-deprecated-declarations -Wno-error +-CFLAGS-tst-lfschk6.cc += -Wno-format -Wno-deprecated-declarations -Wno-error +-LDLIBS-tst-chk4 = -lstdc++ +-LDLIBS-tst-chk5 = -lstdc++ +-LDLIBS-tst-chk6 = -lstdc++ +-LDLIBS-tst-chk8 = -lstdc++ +-LDLIBS-tst-lfschk4 = -lstdc++ +-LDLIBS-tst-lfschk5 = -lstdc++ +-LDLIBS-tst-lfschk6 = -lstdc++ ++define gen-chk-test ++tests-$(1)-chk += tst-fortify-$(1)-$(2)-$(3) ++CFLAGS-tst-fortify-$(1)-$(2)-$(3).$(1) += -D_FORTIFY_SOURCE=$(3) -Wno-format \ ++ -Wno-deprecated-declarations \ ++ -Wno-error ++$(eval $(call cflags-$(2),$(1),$(3))) ++$(objpfx)tst-fortify-$(1)-$(2)-$(3).$(1): tst-fortify.c Makefile ++ ( echo "/* Autogenerated from Makefile. */"; \ ++ echo ""; \ ++ echo "#include \"tst-fortify.c\"" ) > $$@.tmp ++ mv $$@.tmp $$@ ++endef ++ ++chk-extensions = c cc ++chk-types = default lfs ++chk-levels = 1 2 3 ++ ++$(foreach e,$(chk-extensions), \ ++ $(foreach t,$(chk-types), \ ++ $(foreach l,$(chk-levels), \ ++ $(eval $(call gen-chk-test,$(e),$(t),$(l)))))) ++ ++tests-all-chk += $(tests-c-chk) $(tests-cc-chk) ++ ++define link-cc ++LDLIBS-$(1) = -lstdc++ ++endef ++$(foreach t,$(tests-cc-chk), $(eval $(call link-cc,$(t)))) + + # backtrace_symbols only works if we link with -rdynamic. backtrace + # requires unwind tables on most architectures. +@@ -152,19 +181,25 @@ LDFLAGS-tst-backtrace6 = -rdynamic + + CFLAGS-tst-ssp-1.c += -fstack-protector-all + +-tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \ +- tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \ +- tst-chk4 tst-chk5 tst-chk6 tst-chk7 tst-chk8 tst-lfschk4 tst-lfschk5 \ +- tst-lfschk6 tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 \ +- tst-backtrace4 tst-backtrace5 tst-backtrace6 tst-realpath-chk ++tests = backtrace-tst \ ++ tst-longjmp_chk \ ++ test-strcpy_chk \ ++ test-stpcpy_chk \ ++ tst-longjmp_chk2 \ ++ tst-backtrace2 \ ++ tst-backtrace3 \ ++ tst-backtrace4 \ ++ tst-backtrace5 \ ++ tst-backtrace6 \ ++ tst-realpath-chk \ ++ $(tests-all-chk) + + ifeq ($(have-ssp),yes) + tests += tst-ssp-1 + endif + + ifeq (,$(CXX)) +-tests-unsupported = tst-chk4 tst-chk5 tst-chk6 tst-chk8 \ +- tst-lfschk4 tst-lfschk5 tst-lfschk6 ++tests-unsupported = $(tests-cc-chk) + endif + + extra-libs = libSegFault libpcprofile +@@ -191,20 +226,10 @@ ifeq ($(run-built-tests),yes) + LOCALES := de_DE.UTF-8 + include ../gen-locales.mk + +-$(objpfx)tst-chk1.out: $(gen-locales) +-$(objpfx)tst-chk2.out: $(gen-locales) +-$(objpfx)tst-chk3.out: $(gen-locales) +-$(objpfx)tst-chk4.out: $(gen-locales) +-$(objpfx)tst-chk5.out: $(gen-locales) +-$(objpfx)tst-chk6.out: $(gen-locales) +-$(objpfx)tst-chk7.out: $(gen-locales) +-$(objpfx)tst-chk8.out: $(gen-locales) +-$(objpfx)tst-lfschk1.out: $(gen-locales) +-$(objpfx)tst-lfschk2.out: $(gen-locales) +-$(objpfx)tst-lfschk3.out: $(gen-locales) +-$(objpfx)tst-lfschk4.out: $(gen-locales) +-$(objpfx)tst-lfschk5.out: $(gen-locales) +-$(objpfx)tst-lfschk6.out: $(gen-locales) ++define chk-gen-locales ++$(objpfx)$(1).out: $(gen-locales) ++endef ++$(foreach t, $(tests-all-chk), $(eval $(call chk-gen-locales,$(t)))) + endif + + sLIBdir := $(shell echo $(slibdir) | sed 's,lib\(\|64\)$$,\\\\$$LIB,') +diff --git a/debug/tst-chk2.c b/debug/tst-chk2.c +deleted file mode 100644 +index be37ce2d22f0760a..0000000000000000 +--- a/debug/tst-chk2.c ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FORTIFY_SOURCE 1 +-#include "tst-chk1.c" +diff --git a/debug/tst-chk3.c b/debug/tst-chk3.c +deleted file mode 100644 +index 38b8e4fb360ba722..0000000000000000 +--- a/debug/tst-chk3.c ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FORTIFY_SOURCE 2 +-#include "tst-chk1.c" +diff --git a/debug/tst-chk4.cc b/debug/tst-chk4.cc +deleted file mode 100644 +index c82e6aac86038791..0000000000000000 +--- a/debug/tst-chk4.cc ++++ /dev/null +@@ -1 +0,0 @@ +-#include "tst-chk1.c" +diff --git a/debug/tst-chk5.cc b/debug/tst-chk5.cc +deleted file mode 100644 +index be37ce2d22f0760a..0000000000000000 +--- a/debug/tst-chk5.cc ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FORTIFY_SOURCE 1 +-#include "tst-chk1.c" +diff --git a/debug/tst-chk6.cc b/debug/tst-chk6.cc +deleted file mode 100644 +index 38b8e4fb360ba722..0000000000000000 +--- a/debug/tst-chk6.cc ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FORTIFY_SOURCE 2 +-#include "tst-chk1.c" +diff --git a/debug/tst-chk7.c b/debug/tst-chk7.c +deleted file mode 100644 +index 2a7b32381268135c..0000000000000000 +--- a/debug/tst-chk7.c ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FORTIFY_SOURCE 3 +-#include "tst-chk1.c" +diff --git a/debug/tst-chk8.cc b/debug/tst-chk8.cc +deleted file mode 100644 +index 2a7b32381268135c..0000000000000000 +--- a/debug/tst-chk8.cc ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FORTIFY_SOURCE 3 +-#include "tst-chk1.c" +diff --git a/debug/tst-chk1.c b/debug/tst-fortify.c +similarity index 100% +rename from debug/tst-chk1.c +rename to debug/tst-fortify.c +diff --git a/debug/tst-lfschk1.c b/debug/tst-lfschk1.c +deleted file mode 100644 +index f3e6d47d5e4484c3..0000000000000000 +--- a/debug/tst-lfschk1.c ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FILE_OFFSET_BITS 64 +-#include "tst-chk1.c" +diff --git a/debug/tst-lfschk2.c b/debug/tst-lfschk2.c +deleted file mode 100644 +index 95d4db1d32d2eeb3..0000000000000000 +--- a/debug/tst-lfschk2.c ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FILE_OFFSET_BITS 64 +-#include "tst-chk2.c" +diff --git a/debug/tst-lfschk3.c b/debug/tst-lfschk3.c +deleted file mode 100644 +index 50a1ae1258f1553d..0000000000000000 +--- a/debug/tst-lfschk3.c ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FILE_OFFSET_BITS 64 +-#include "tst-chk3.c" +diff --git a/debug/tst-lfschk4.cc b/debug/tst-lfschk4.cc +deleted file mode 100644 +index f3e6d47d5e4484c3..0000000000000000 +--- a/debug/tst-lfschk4.cc ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FILE_OFFSET_BITS 64 +-#include "tst-chk1.c" +diff --git a/debug/tst-lfschk5.cc b/debug/tst-lfschk5.cc +deleted file mode 100644 +index 95d4db1d32d2eeb3..0000000000000000 +--- a/debug/tst-lfschk5.cc ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FILE_OFFSET_BITS 64 +-#include "tst-chk2.c" +diff --git a/debug/tst-lfschk6.cc b/debug/tst-lfschk6.cc +deleted file mode 100644 +index 50a1ae1258f1553d..0000000000000000 +--- a/debug/tst-lfschk6.cc ++++ /dev/null +@@ -1,2 +0,0 @@ +-#define _FILE_OFFSET_BITS 64 +-#include "tst-chk3.c" diff --git a/SOURCES/glibc-rh2033684-2.patch b/SOURCES/glibc-rh2033684-2.patch new file mode 100644 index 0000000..4651008 --- /dev/null +++ b/SOURCES/glibc-rh2033684-2.patch @@ -0,0 +1,101 @@ +commit c43c5796121bc5bcc0867f02e5536874aa8196c1 +Author: Siddhesh Poyarekar +Date: Wed Dec 30 11:54:00 2020 +0530 + + Introduce _FORTIFY_SOURCE=3 + + Introduce a new _FORTIFY_SOURCE level of 3 to enable additional + fortifications that may have a noticeable performance impact, allowing + more fortification coverage at the cost of some performance. + + With llvm 9.0 or later, this will replace the use of + __builtin_object_size with __builtin_dynamic_object_size. + + __builtin_dynamic_object_size + ----------------------------- + + __builtin_dynamic_object_size is an LLVM builtin that is similar to + __builtin_object_size. In addition to what __builtin_object_size + does, i.e. replace the builtin call with a constant object size, + __builtin_dynamic_object_size will replace the call site with an + expression that evaluates to the object size, thus expanding its + applicability. In practice, __builtin_dynamic_object_size evaluates + these expressions through malloc/calloc calls that it can associate + with the object being evaluated. + + A simple motivating example is below; -D_FORTIFY_SOURCE=2 would miss + this and emit memcpy, but -D_FORTIFY_SOURCE=3 with the help of + __builtin_dynamic_object_size is able to emit __memcpy_chk with the + allocation size expression passed into the function: + + void *copy_obj (const void *src, size_t alloc, size_t copysize) + { + void *obj = malloc (alloc); + memcpy (obj, src, copysize); + return obj; + } + + Limitations + ----------- + + If the object was allocated elsewhere that the compiler cannot see, or + if it was allocated in the function with a function that the compiler + does not recognize as an allocator then __builtin_dynamic_object_size + also returns -1. + + Further, the expression used to compute object size may be non-trivial + and may potentially incur a noticeable performance impact. These + fortifications are hence enabled at a new _FORTIFY_SOURCE level to + allow developers to make a choice on the tradeoff according to their + environment. + +diff --git a/include/features.h b/include/features.h +index ea7673ee115bcf0a..fe9fe16d034fad1b 100644 +--- a/include/features.h ++++ b/include/features.h +@@ -381,6 +381,11 @@ + # warning _FORTIFY_SOURCE requires compiling with optimization (-O) + # elif !__GNUC_PREREQ (4, 1) + # warning _FORTIFY_SOURCE requires GCC 4.1 or later ++# elif _FORTIFY_SOURCE > 2 && __glibc_clang_prereq (9, 0) ++# if _FORTIFY_SOURCE > 3 ++# warning _FORTIFY_SOURCE > 3 is treated like 3 on this platform ++# endif ++# define __USE_FORTIFY_LEVEL 3 + # elif _FORTIFY_SOURCE > 1 + # if _FORTIFY_SOURCE > 2 + # warning _FORTIFY_SOURCE > 2 is treated like 2 on this platform +diff --git a/manual/creature.texi b/manual/creature.texi +index 8876b2ab779c988f..64f361f27a7d6cdf 100644 +--- a/manual/creature.texi ++++ b/manual/creature.texi +@@ -247,7 +247,8 @@ included. + @standards{GNU, (none)} + If this macro is defined to @math{1}, security hardening is added to + various library functions. If defined to @math{2}, even stricter +-checks are applied. ++checks are applied. If defined to @math{3}, @theglibc{} may also use ++checks that may have an additional performance overhead. + @end defvr + + @defvr Macro _REENTRANT +diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h +index 3f6fe3cc8563b493..1e39307b0ebcf38f 100644 +--- a/misc/sys/cdefs.h ++++ b/misc/sys/cdefs.h +@@ -123,6 +123,15 @@ + #define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1) + #define __bos0(ptr) __builtin_object_size (ptr, 0) + ++/* Use __builtin_dynamic_object_size at _FORTIFY_SOURCE=3 when available. */ ++#if __USE_FORTIFY_LEVEL == 3 && __glibc_clang_prereq (9, 0) ++# define __glibc_objsize0(__o) __builtin_dynamic_object_size (__o, 0) ++# define __glibc_objsize(__o) __builtin_dynamic_object_size (__o, 1) ++#else ++# define __glibc_objsize0(__o) __bos0 (__o) ++# define __glibc_objsize(__o) __bos (__o) ++#endif ++ + #if __GNUC_PREREQ (4,3) + # define __warndecl(name, msg) \ + extern void name (void) __attribute__((__warning__ (msg))) diff --git a/SOURCES/glibc-rh2033684-3.patch b/SOURCES/glibc-rh2033684-3.patch new file mode 100644 index 0000000..b8d0093 --- /dev/null +++ b/SOURCES/glibc-rh2033684-3.patch @@ -0,0 +1,43 @@ +commit 7163ace3318d666d40771f5c8e7c4a148827070f +Author: Siddhesh Poyarekar +Date: Thu Nov 12 12:09:56 2020 +0530 + + Use __builtin___stpncpy_chk when available + + The builtin has been available in gcc since 4.7.0 and in clang since + 2.6. This fixes stpncpy fortification with clang since it does a + better job of plugging in __stpncpy_chk in the right place than the + header hackery. + + This has been tested by building and running all tests with gcc 10.2.1 + and also with clang tip as of a few days ago (just the tests in debug/ + since running all tests don't work with clang at the moment) to make + sure that both compilers pass the stpncpy tests. + +diff --git a/string/bits/string_fortified.h b/string/bits/string_fortified.h +index a07ab0dbc8c8dd5b..4ed6755a6c1ca247 100644 +--- a/string/bits/string_fortified.h ++++ b/string/bits/string_fortified.h +@@ -106,7 +106,13 @@ __NTH (strncpy (char *__restrict __dest, const char *__restrict __src, + return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest)); + } + +-/* XXX We have no corresponding builtin yet. */ ++#if __GNUC_PREREQ (4, 7) || __glibc_clang_prereq (2, 6) ++__fortify_function char * ++__NTH (stpncpy (char *__dest, const char *__src, size_t __n)) ++{ ++ return __builtin___stpncpy_chk (__dest, __src, __n, __bos (__dest)); ++} ++#else + extern char *__stpncpy_chk (char *__dest, const char *__src, size_t __n, + size_t __destlen) __THROW; + extern char *__REDIRECT_NTH (__stpncpy_alias, (char *__dest, const char *__src, +@@ -120,6 +126,7 @@ __NTH (stpncpy (char *__dest, const char *__src, size_t __n)) + return __stpncpy_chk (__dest, __src, __n, __bos (__dest)); + return __stpncpy_alias (__dest, __src, __n); + } ++#endif + + + __fortify_function char * diff --git a/SOURCES/glibc-rh2033684-4.patch b/SOURCES/glibc-rh2033684-4.patch new file mode 100644 index 0000000..ebd0c33 --- /dev/null +++ b/SOURCES/glibc-rh2033684-4.patch @@ -0,0 +1,161 @@ +commit 2a3224c53653214cbba2ec23424702193c80ea3b +Author: Siddhesh Poyarekar +Date: Wed Dec 30 11:09:58 2020 +0530 + + string: Enable __FORTIFY_LEVEL=3 + + This change enhances fortified string functions to use + __builtin_dynamic_object_size under _FORTIFY_SOURCE=3 whenever the + compiler supports it. + +# Conflicts: +# string/bits/string_fortified.h + +Conflict resolved to retain __GNUC_PREREQ (5,0) macro check in RHEL-8 +glibc. + +diff --git a/include/string.h b/include/string.h +index 4d622f1c0305e78e..bbc97082661caf42 100644 +--- a/include/string.h ++++ b/include/string.h +@@ -119,10 +119,11 @@ libc_hidden_proto (__ffs) + void __explicit_bzero_chk_internal (void *, size_t, size_t) + __THROW __nonnull ((1)) attribute_hidden; + # define explicit_bzero(buf, len) \ +- __explicit_bzero_chk_internal (buf, len, __bos0 (buf)) ++ __explicit_bzero_chk_internal (buf, len, __glibc_objsize0 (buf)) + #elif !IS_IN (nonlib) + void __explicit_bzero_chk (void *, size_t, size_t) __THROW __nonnull ((1)); +-# define explicit_bzero(buf, len) __explicit_bzero_chk (buf, len, __bos0 (buf)) ++# define explicit_bzero(buf, len) __explicit_bzero_chk (buf, len, \ ++ __glibc_objsize0 (buf)) + #endif + + libc_hidden_builtin_proto (memchr) +diff --git a/string/bits/string_fortified.h b/string/bits/string_fortified.h +index 4ed6755a6c1ca247..27ec273ec41cd81c 100644 +--- a/string/bits/string_fortified.h ++++ b/string/bits/string_fortified.h +@@ -31,13 +31,15 @@ __fortify_function void * + __NTH (memcpy (void *__restrict __dest, const void *__restrict __src, + size_t __len)) + { +- return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest)); ++ return __builtin___memcpy_chk (__dest, __src, __len, ++ __glibc_objsize0 (__dest)); + } + + __fortify_function void * + __NTH (memmove (void *__dest, const void *__src, size_t __len)) + { +- return __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest)); ++ return __builtin___memmove_chk (__dest, __src, __len, ++ __glibc_objsize0 (__dest)); + } + + #ifdef __USE_GNU +@@ -45,7 +47,8 @@ __fortify_function void * + __NTH (mempcpy (void *__restrict __dest, const void *__restrict __src, + size_t __len)) + { +- return __builtin___mempcpy_chk (__dest, __src, __len, __bos0 (__dest)); ++ return __builtin___mempcpy_chk (__dest, __src, __len, ++ __glibc_objsize0 (__dest)); + } + #endif + +@@ -68,7 +71,8 @@ __NTH (memset (void *__dest, int __ch, size_t __len)) + return __dest; + } + #endif +- return __builtin___memset_chk (__dest, __ch, __len, __bos0 (__dest)); ++ return __builtin___memset_chk (__dest, __ch, __len, ++ __glibc_objsize0 (__dest)); + } + + #ifdef __USE_MISC +@@ -80,21 +84,21 @@ void __explicit_bzero_chk (void *__dest, size_t __len, size_t __destlen) + __fortify_function void + __NTH (explicit_bzero (void *__dest, size_t __len)) + { +- __explicit_bzero_chk (__dest, __len, __bos0 (__dest)); ++ __explicit_bzero_chk (__dest, __len, __glibc_objsize0 (__dest)); + } + #endif + + __fortify_function char * + __NTH (strcpy (char *__restrict __dest, const char *__restrict __src)) + { +- return __builtin___strcpy_chk (__dest, __src, __bos (__dest)); ++ return __builtin___strcpy_chk (__dest, __src, __glibc_objsize (__dest)); + } + + #ifdef __USE_GNU + __fortify_function char * + __NTH (stpcpy (char *__restrict __dest, const char *__restrict __src)) + { +- return __builtin___stpcpy_chk (__dest, __src, __bos (__dest)); ++ return __builtin___stpcpy_chk (__dest, __src, __glibc_objsize (__dest)); + } + #endif + +@@ -103,14 +107,16 @@ __fortify_function char * + __NTH (strncpy (char *__restrict __dest, const char *__restrict __src, + size_t __len)) + { +- return __builtin___strncpy_chk (__dest, __src, __len, __bos (__dest)); ++ return __builtin___strncpy_chk (__dest, __src, __len, ++ __glibc_objsize (__dest)); + } + + #if __GNUC_PREREQ (4, 7) || __glibc_clang_prereq (2, 6) + __fortify_function char * + __NTH (stpncpy (char *__dest, const char *__src, size_t __n)) + { +- return __builtin___stpncpy_chk (__dest, __src, __n, __bos (__dest)); ++ return __builtin___stpncpy_chk (__dest, __src, __n, ++ __glibc_objsize (__dest)); + } + #else + extern char *__stpncpy_chk (char *__dest, const char *__src, size_t __n, +@@ -132,7 +138,7 @@ __NTH (stpncpy (char *__dest, const char *__src, size_t __n)) + __fortify_function char * + __NTH (strcat (char *__restrict __dest, const char *__restrict __src)) + { +- return __builtin___strcat_chk (__dest, __src, __bos (__dest)); ++ return __builtin___strcat_chk (__dest, __src, __glibc_objsize (__dest)); + } + + +@@ -140,7 +146,8 @@ __fortify_function char * + __NTH (strncat (char *__restrict __dest, const char *__restrict __src, + size_t __len)) + { +- return __builtin___strncat_chk (__dest, __src, __len, __bos (__dest)); ++ return __builtin___strncat_chk (__dest, __src, __len, ++ __glibc_objsize (__dest)); + } + + #endif /* bits/string_fortified.h */ +diff --git a/string/bits/strings_fortified.h b/string/bits/strings_fortified.h +index d9b2804525cfa994..871515bd2cba1f8a 100644 +--- a/string/bits/strings_fortified.h ++++ b/string/bits/strings_fortified.h +@@ -22,13 +22,15 @@ + __fortify_function void + __NTH (bcopy (const void *__src, void *__dest, size_t __len)) + { +- (void) __builtin___memmove_chk (__dest, __src, __len, __bos0 (__dest)); ++ (void) __builtin___memmove_chk (__dest, __src, __len, ++ __glibc_objsize0 (__dest)); + } + + __fortify_function void + __NTH (bzero (void *__dest, size_t __len)) + { +- (void) __builtin___memset_chk (__dest, '\0', __len, __bos0 (__dest)); ++ (void) __builtin___memset_chk (__dest, '\0', __len, ++ __glibc_objsize0 (__dest)); + } + + #endif diff --git a/SOURCES/glibc-rh2033684-5.patch b/SOURCES/glibc-rh2033684-5.patch new file mode 100644 index 0000000..8c1f7f3 --- /dev/null +++ b/SOURCES/glibc-rh2033684-5.patch @@ -0,0 +1,963 @@ +commit f9de8bfe1a731c309b91d175b4f6f4aeb786effa +Author: Siddhesh Poyarekar +Date: Tue Dec 15 23:50:09 2020 +0530 + + nonstring: Enable __FORTIFY_LEVEL=3 + + Use __builtin_dynamic_object_size in the remaining functions that + don't have compiler builtins as is the case for string functions. + +diff --git a/io/bits/poll2.h b/io/bits/poll2.h +index 7e8406b87d6319f8..f47fd9ad0945234f 100644 +--- a/io/bits/poll2.h ++++ b/io/bits/poll2.h +@@ -35,12 +35,13 @@ extern int __REDIRECT (__poll_chk_warn, (struct pollfd *__fds, nfds_t __nfds, + __fortify_function int + poll (struct pollfd *__fds, nfds_t __nfds, int __timeout) + { +- if (__bos (__fds) != (__SIZE_TYPE__) -1) ++ if (__glibc_objsize (__fds) != (__SIZE_TYPE__) -1) + { + if (! __builtin_constant_p (__nfds)) +- return __poll_chk (__fds, __nfds, __timeout, __bos (__fds)); +- else if (__bos (__fds) / sizeof (*__fds) < __nfds) +- return __poll_chk_warn (__fds, __nfds, __timeout, __bos (__fds)); ++ return __poll_chk (__fds, __nfds, __timeout, __glibc_objsize (__fds)); ++ else if (__glibc_objsize (__fds) / sizeof (*__fds) < __nfds) ++ return __poll_chk_warn (__fds, __nfds, __timeout, ++ __glibc_objsize (__fds)); + } + + return __poll_alias (__fds, __nfds, __timeout); +@@ -65,13 +66,14 @@ __fortify_function int + ppoll (struct pollfd *__fds, nfds_t __nfds, const struct timespec *__timeout, + const __sigset_t *__ss) + { +- if (__bos (__fds) != (__SIZE_TYPE__) -1) ++ if (__glibc_objsize (__fds) != (__SIZE_TYPE__) -1) + { + if (! __builtin_constant_p (__nfds)) +- return __ppoll_chk (__fds, __nfds, __timeout, __ss, __bos (__fds)); +- else if (__bos (__fds) / sizeof (*__fds) < __nfds) ++ return __ppoll_chk (__fds, __nfds, __timeout, __ss, ++ __glibc_objsize (__fds)); ++ else if (__glibc_objsize (__fds) / sizeof (*__fds) < __nfds) + return __ppoll_chk_warn (__fds, __nfds, __timeout, __ss, +- __bos (__fds)); ++ __glibc_objsize (__fds)); + } + + return __ppoll_alias (__fds, __nfds, __timeout, __ss); +diff --git a/libio/bits/stdio.h b/libio/bits/stdio.h +index 4ab919031f77a960..1372d4bf70c43d53 100644 +--- a/libio/bits/stdio.h ++++ b/libio/bits/stdio.h +@@ -31,7 +31,7 @@ + + + #ifdef __USE_EXTERN_INLINES +-/* For -D_FORTIFY_SOURCE{,=2} bits/stdio2.h will define a different ++/* For -D_FORTIFY_SOURCE{,=2,=3} bits/stdio2.h will define a different + inline. */ + # if !(__USE_FORTIFY_LEVEL > 0 && defined __fortify_function) + /* Write formatted output to stdout from argument list ARG. */ +diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h +index 11651506a67daea0..2cd69f44cfadfc9f 100644 +--- a/libio/bits/stdio2.h ++++ b/libio/bits/stdio2.h +@@ -34,12 +34,13 @@ __fortify_function int + __NTH (sprintf (char *__restrict __s, const char *__restrict __fmt, ...)) + { + return __builtin___sprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, +- __bos (__s), __fmt, __va_arg_pack ()); ++ __glibc_objsize (__s), __fmt, ++ __va_arg_pack ()); + } + #elif !defined __cplusplus + # define sprintf(str, ...) \ +- __builtin___sprintf_chk (str, __USE_FORTIFY_LEVEL - 1, __bos (str), \ +- __VA_ARGS__) ++ __builtin___sprintf_chk (str, __USE_FORTIFY_LEVEL - 1, \ ++ __glibc_objsize (str), __VA_ARGS__) + #endif + + __fortify_function int +@@ -47,7 +48,7 @@ __NTH (vsprintf (char *__restrict __s, const char *__restrict __fmt, + __gnuc_va_list __ap)) + { + return __builtin___vsprintf_chk (__s, __USE_FORTIFY_LEVEL - 1, +- __bos (__s), __fmt, __ap); ++ __glibc_objsize (__s), __fmt, __ap); + } + + #if defined __USE_ISOC99 || defined __USE_UNIX98 +@@ -65,12 +66,13 @@ __NTH (snprintf (char *__restrict __s, size_t __n, + const char *__restrict __fmt, ...)) + { + return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, +- __bos (__s), __fmt, __va_arg_pack ()); ++ __glibc_objsize (__s), __fmt, ++ __va_arg_pack ()); + } + # elif !defined __cplusplus + # define snprintf(str, len, ...) \ +- __builtin___snprintf_chk (str, len, __USE_FORTIFY_LEVEL - 1, __bos (str), \ +- __VA_ARGS__) ++ __builtin___snprintf_chk (str, len, __USE_FORTIFY_LEVEL - 1, \ ++ __glibc_objsize (str), __VA_ARGS__) + # endif + + __fortify_function int +@@ -78,7 +80,7 @@ __NTH (vsnprintf (char *__restrict __s, size_t __n, + const char *__restrict __fmt, __gnuc_va_list __ap)) + { + return __builtin___vsnprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, +- __bos (__s), __fmt, __ap); ++ __glibc_objsize (__s), __fmt, __ap); + } + + #endif +@@ -234,8 +236,8 @@ extern char *__REDIRECT (__gets_warn, (char *__str), gets) + __fortify_function __wur char * + gets (char *__str) + { +- if (__bos (__str) != (size_t) -1) +- return __gets_chk (__str, __bos (__str)); ++ if (__glibc_objsize (__str) != (size_t) -1) ++ return __gets_chk (__str, __glibc_objsize (__str)); + return __gets_warn (__str); + } + #endif +@@ -254,13 +256,13 @@ extern char *__REDIRECT (__fgets_chk_warn, + __fortify_function __wur char * + fgets (char *__restrict __s, int __n, FILE *__restrict __stream) + { +- if (__bos (__s) != (size_t) -1) ++ if (__glibc_objsize (__s) != (size_t) -1) + { + if (!__builtin_constant_p (__n) || __n <= 0) +- return __fgets_chk (__s, __bos (__s), __n, __stream); ++ return __fgets_chk (__s, __glibc_objsize (__s), __n, __stream); + +- if ((size_t) __n > __bos (__s)) +- return __fgets_chk_warn (__s, __bos (__s), __n, __stream); ++ if ((size_t) __n > __glibc_objsize (__s)) ++ return __fgets_chk_warn (__s, __glibc_objsize (__s), __n, __stream); + } + return __fgets_alias (__s, __n, __stream); + } +@@ -284,15 +286,17 @@ __fortify_function __wur size_t + fread (void *__restrict __ptr, size_t __size, size_t __n, + FILE *__restrict __stream) + { +- if (__bos0 (__ptr) != (size_t) -1) ++ if (__glibc_objsize0 (__ptr) != (size_t) -1) + { + if (!__builtin_constant_p (__size) + || !__builtin_constant_p (__n) + || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2))) +- return __fread_chk (__ptr, __bos0 (__ptr), __size, __n, __stream); ++ return __fread_chk (__ptr, __glibc_objsize0 (__ptr), __size, __n, ++ __stream); + +- if (__size * __n > __bos0 (__ptr)) +- return __fread_chk_warn (__ptr, __bos0 (__ptr), __size, __n, __stream); ++ if (__size * __n > __glibc_objsize0 (__ptr)) ++ return __fread_chk_warn (__ptr, __glibc_objsize0 (__ptr), __size, __n, ++ __stream); + } + return __fread_alias (__ptr, __size, __n, __stream); + } +@@ -312,13 +316,15 @@ extern char *__REDIRECT (__fgets_unlocked_chk_warn, + __fortify_function __wur char * + fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream) + { +- if (__bos (__s) != (size_t) -1) ++ if (__glibc_objsize (__s) != (size_t) -1) + { + if (!__builtin_constant_p (__n) || __n <= 0) +- return __fgets_unlocked_chk (__s, __bos (__s), __n, __stream); ++ return __fgets_unlocked_chk (__s, __glibc_objsize (__s), __n, ++ __stream); + +- if ((size_t) __n > __bos (__s)) +- return __fgets_unlocked_chk_warn (__s, __bos (__s), __n, __stream); ++ if ((size_t) __n > __glibc_objsize (__s)) ++ return __fgets_unlocked_chk_warn (__s, __glibc_objsize (__s), __n, ++ __stream); + } + return __fgets_unlocked_alias (__s, __n, __stream); + } +@@ -345,17 +351,17 @@ __fortify_function __wur size_t + fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n, + FILE *__restrict __stream) + { +- if (__bos0 (__ptr) != (size_t) -1) ++ if (__glibc_objsize0 (__ptr) != (size_t) -1) + { + if (!__builtin_constant_p (__size) + || !__builtin_constant_p (__n) + || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2))) +- return __fread_unlocked_chk (__ptr, __bos0 (__ptr), __size, __n, +- __stream); ++ return __fread_unlocked_chk (__ptr, __glibc_objsize0 (__ptr), __size, ++ __n, __stream); + +- if (__size * __n > __bos0 (__ptr)) +- return __fread_unlocked_chk_warn (__ptr, __bos0 (__ptr), __size, __n, +- __stream); ++ if (__size * __n > __glibc_objsize0 (__ptr)) ++ return __fread_unlocked_chk_warn (__ptr, __glibc_objsize0 (__ptr), ++ __size, __n, __stream); + } + + # ifdef __USE_EXTERN_INLINES +diff --git a/posix/bits/unistd.h b/posix/bits/unistd.h +index 9a749dccf8de65cd..a0c4dcfe9c61a7b8 100644 +--- a/posix/bits/unistd.h ++++ b/posix/bits/unistd.h +@@ -33,13 +33,14 @@ extern ssize_t __REDIRECT (__read_chk_warn, + __fortify_function __wur ssize_t + read (int __fd, void *__buf, size_t __nbytes) + { +- if (__bos0 (__buf) != (size_t) -1) ++ if (__glibc_objsize0 (__buf) != (size_t) -1) + { + if (!__builtin_constant_p (__nbytes)) +- return __read_chk (__fd, __buf, __nbytes, __bos0 (__buf)); ++ return __read_chk (__fd, __buf, __nbytes, __glibc_objsize0 (__buf)); + +- if (__nbytes > __bos0 (__buf)) +- return __read_chk_warn (__fd, __buf, __nbytes, __bos0 (__buf)); ++ if (__nbytes > __glibc_objsize0 (__buf)) ++ return __read_chk_warn (__fd, __buf, __nbytes, ++ __glibc_objsize0 (__buf)); + } + return __read_alias (__fd, __buf, __nbytes); + } +@@ -71,14 +72,15 @@ extern ssize_t __REDIRECT (__pread64_chk_warn, + __fortify_function __wur ssize_t + pread (int __fd, void *__buf, size_t __nbytes, __off_t __offset) + { +- if (__bos0 (__buf) != (size_t) -1) ++ if (__glibc_objsize0 (__buf) != (size_t) -1) + { + if (!__builtin_constant_p (__nbytes)) +- return __pread_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf)); ++ return __pread_chk (__fd, __buf, __nbytes, __offset, ++ __glibc_objsize0 (__buf)); + +- if ( __nbytes > __bos0 (__buf)) ++ if ( __nbytes > __glibc_objsize0 (__buf)) + return __pread_chk_warn (__fd, __buf, __nbytes, __offset, +- __bos0 (__buf)); ++ __glibc_objsize0 (__buf)); + } + return __pread_alias (__fd, __buf, __nbytes, __offset); + } +@@ -86,14 +88,15 @@ pread (int __fd, void *__buf, size_t __nbytes, __off_t __offset) + __fortify_function __wur ssize_t + pread (int __fd, void *__buf, size_t __nbytes, __off64_t __offset) + { +- if (__bos0 (__buf) != (size_t) -1) ++ if (__glibc_objsize0 (__buf) != (size_t) -1) + { + if (!__builtin_constant_p (__nbytes)) +- return __pread64_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf)); ++ return __pread64_chk (__fd, __buf, __nbytes, __offset, ++ __glibc_objsize0 (__buf)); + +- if ( __nbytes > __bos0 (__buf)) ++ if ( __nbytes > __glibc_objsize0 (__buf)) + return __pread64_chk_warn (__fd, __buf, __nbytes, __offset, +- __bos0 (__buf)); ++ __glibc_objsize0 (__buf)); + } + + return __pread64_alias (__fd, __buf, __nbytes, __offset); +@@ -104,14 +107,15 @@ pread (int __fd, void *__buf, size_t __nbytes, __off64_t __offset) + __fortify_function __wur ssize_t + pread64 (int __fd, void *__buf, size_t __nbytes, __off64_t __offset) + { +- if (__bos0 (__buf) != (size_t) -1) ++ if (__glibc_objsize0 (__buf) != (size_t) -1) + { + if (!__builtin_constant_p (__nbytes)) +- return __pread64_chk (__fd, __buf, __nbytes, __offset, __bos0 (__buf)); ++ return __pread64_chk (__fd, __buf, __nbytes, __offset, ++ __glibc_objsize0 (__buf)); + +- if ( __nbytes > __bos0 (__buf)) ++ if ( __nbytes > __glibc_objsize0 (__buf)) + return __pread64_chk_warn (__fd, __buf, __nbytes, __offset, +- __bos0 (__buf)); ++ __glibc_objsize0 (__buf)); + } + + return __pread64_alias (__fd, __buf, __nbytes, __offset); +@@ -139,13 +143,14 @@ __fortify_function __nonnull ((1, 2)) __wur ssize_t + __NTH (readlink (const char *__restrict __path, char *__restrict __buf, + size_t __len)) + { +- if (__bos (__buf) != (size_t) -1) ++ if (__glibc_objsize (__buf) != (size_t) -1) + { + if (!__builtin_constant_p (__len)) +- return __readlink_chk (__path, __buf, __len, __bos (__buf)); ++ return __readlink_chk (__path, __buf, __len, __glibc_objsize (__buf)); + +- if ( __len > __bos (__buf)) +- return __readlink_chk_warn (__path, __buf, __len, __bos (__buf)); ++ if ( __len > __glibc_objsize (__buf)) ++ return __readlink_chk_warn (__path, __buf, __len, ++ __glibc_objsize (__buf)); + } + return __readlink_alias (__path, __buf, __len); + } +@@ -173,14 +178,15 @@ __fortify_function __nonnull ((2, 3)) __wur ssize_t + __NTH (readlinkat (int __fd, const char *__restrict __path, + char *__restrict __buf, size_t __len)) + { +- if (__bos (__buf) != (size_t) -1) ++ if (__glibc_objsize (__buf) != (size_t) -1) + { + if (!__builtin_constant_p (__len)) +- return __readlinkat_chk (__fd, __path, __buf, __len, __bos (__buf)); ++ return __readlinkat_chk (__fd, __path, __buf, __len, ++ __glibc_objsize (__buf)); + +- if (__len > __bos (__buf)) ++ if (__len > __glibc_objsize (__buf)) + return __readlinkat_chk_warn (__fd, __path, __buf, __len, +- __bos (__buf)); ++ __glibc_objsize (__buf)); + } + return __readlinkat_alias (__fd, __path, __buf, __len); + } +@@ -199,13 +205,13 @@ extern char *__REDIRECT_NTH (__getcwd_chk_warn, + __fortify_function __wur char * + __NTH (getcwd (char *__buf, size_t __size)) + { +- if (__bos (__buf) != (size_t) -1) ++ if (__glibc_objsize (__buf) != (size_t) -1) + { + if (!__builtin_constant_p (__size)) +- return __getcwd_chk (__buf, __size, __bos (__buf)); ++ return __getcwd_chk (__buf, __size, __glibc_objsize (__buf)); + +- if (__size > __bos (__buf)) +- return __getcwd_chk_warn (__buf, __size, __bos (__buf)); ++ if (__size > __glibc_objsize (__buf)) ++ return __getcwd_chk_warn (__buf, __size, __glibc_objsize (__buf)); + } + return __getcwd_alias (__buf, __size); + } +@@ -220,8 +226,8 @@ extern char *__REDIRECT_NTH (__getwd_warn, (char *__buf), getwd) + __fortify_function __nonnull ((1)) __attribute_deprecated__ __wur char * + __NTH (getwd (char *__buf)) + { +- if (__bos (__buf) != (size_t) -1) +- return __getwd_chk (__buf, __bos (__buf)); ++ if (__glibc_objsize (__buf) != (size_t) -1) ++ return __getwd_chk (__buf, __glibc_objsize (__buf)); + return __getwd_warn (__buf); + } + #endif +@@ -239,13 +245,14 @@ extern size_t __REDIRECT_NTH (__confstr_chk_warn, + __fortify_function size_t + __NTH (confstr (int __name, char *__buf, size_t __len)) + { +- if (__bos (__buf) != (size_t) -1) ++ if (__glibc_objsize (__buf) != (size_t) -1) + { + if (!__builtin_constant_p (__len)) +- return __confstr_chk (__name, __buf, __len, __bos (__buf)); ++ return __confstr_chk (__name, __buf, __len, __glibc_objsize (__buf)); + +- if (__bos (__buf) < __len) +- return __confstr_chk_warn (__name, __buf, __len, __bos (__buf)); ++ if (__glibc_objsize (__buf) < __len) ++ return __confstr_chk_warn (__name, __buf, __len, ++ __glibc_objsize (__buf)); + } + return __confstr_alias (__name, __buf, __len); + } +@@ -264,13 +271,13 @@ extern int __REDIRECT_NTH (__getgroups_chk_warn, + __fortify_function int + __NTH (getgroups (int __size, __gid_t __list[])) + { +- if (__bos (__list) != (size_t) -1) ++ if (__glibc_objsize (__list) != (size_t) -1) + { + if (!__builtin_constant_p (__size) || __size < 0) +- return __getgroups_chk (__size, __list, __bos (__list)); ++ return __getgroups_chk (__size, __list, __glibc_objsize (__list)); + +- if (__size * sizeof (__gid_t) > __bos (__list)) +- return __getgroups_chk_warn (__size, __list, __bos (__list)); ++ if (__size * sizeof (__gid_t) > __glibc_objsize (__list)) ++ return __getgroups_chk_warn (__size, __list, __glibc_objsize (__list)); + } + return __getgroups_alias (__size, __list); + } +@@ -290,13 +297,15 @@ extern int __REDIRECT_NTH (__ttyname_r_chk_warn, + __fortify_function int + __NTH (ttyname_r (int __fd, char *__buf, size_t __buflen)) + { +- if (__bos (__buf) != (size_t) -1) ++ if (__glibc_objsize (__buf) != (size_t) -1) + { + if (!__builtin_constant_p (__buflen)) +- return __ttyname_r_chk (__fd, __buf, __buflen, __bos (__buf)); ++ return __ttyname_r_chk (__fd, __buf, __buflen, ++ __glibc_objsize (__buf)); + +- if (__buflen > __bos (__buf)) +- return __ttyname_r_chk_warn (__fd, __buf, __buflen, __bos (__buf)); ++ if (__buflen > __glibc_objsize (__buf)) ++ return __ttyname_r_chk_warn (__fd, __buf, __buflen, ++ __glibc_objsize (__buf)); + } + return __ttyname_r_alias (__fd, __buf, __buflen); + } +@@ -316,13 +325,14 @@ extern int __REDIRECT (__getlogin_r_chk_warn, + __fortify_function int + getlogin_r (char *__buf, size_t __buflen) + { +- if (__bos (__buf) != (size_t) -1) ++ if (__glibc_objsize (__buf) != (size_t) -1) + { + if (!__builtin_constant_p (__buflen)) +- return __getlogin_r_chk (__buf, __buflen, __bos (__buf)); ++ return __getlogin_r_chk (__buf, __buflen, __glibc_objsize (__buf)); + +- if (__buflen > __bos (__buf)) +- return __getlogin_r_chk_warn (__buf, __buflen, __bos (__buf)); ++ if (__buflen > __glibc_objsize (__buf)) ++ return __getlogin_r_chk_warn (__buf, __buflen, ++ __glibc_objsize (__buf)); + } + return __getlogin_r_alias (__buf, __buflen); + } +@@ -343,13 +353,14 @@ extern int __REDIRECT_NTH (__gethostname_chk_warn, + __fortify_function int + __NTH (gethostname (char *__buf, size_t __buflen)) + { +- if (__bos (__buf) != (size_t) -1) ++ if (__glibc_objsize (__buf) != (size_t) -1) + { + if (!__builtin_constant_p (__buflen)) +- return __gethostname_chk (__buf, __buflen, __bos (__buf)); ++ return __gethostname_chk (__buf, __buflen, __glibc_objsize (__buf)); + +- if (__buflen > __bos (__buf)) +- return __gethostname_chk_warn (__buf, __buflen, __bos (__buf)); ++ if (__buflen > __glibc_objsize (__buf)) ++ return __gethostname_chk_warn (__buf, __buflen, ++ __glibc_objsize (__buf)); + } + return __gethostname_alias (__buf, __buflen); + } +@@ -372,13 +383,14 @@ extern int __REDIRECT_NTH (__getdomainname_chk_warn, + __fortify_function int + __NTH (getdomainname (char *__buf, size_t __buflen)) + { +- if (__bos (__buf) != (size_t) -1) ++ if (__glibc_objsize (__buf) != (size_t) -1) + { + if (!__builtin_constant_p (__buflen)) +- return __getdomainname_chk (__buf, __buflen, __bos (__buf)); ++ return __getdomainname_chk (__buf, __buflen, __glibc_objsize (__buf)); + +- if (__buflen > __bos (__buf)) +- return __getdomainname_chk_warn (__buf, __buflen, __bos (__buf)); ++ if (__buflen > __glibc_objsize (__buf)) ++ return __getdomainname_chk_warn (__buf, __buflen, ++ __glibc_objsize (__buf)); + } + return __getdomainname_alias (__buf, __buflen); + } +diff --git a/socket/bits/socket2.h b/socket/bits/socket2.h +index a129e697352fd7cb..729e5a4cc1f4cb92 100644 +--- a/socket/bits/socket2.h ++++ b/socket/bits/socket2.h +@@ -33,13 +33,15 @@ extern ssize_t __REDIRECT (__recv_chk_warn, + __fortify_function ssize_t + recv (int __fd, void *__buf, size_t __n, int __flags) + { +- if (__bos0 (__buf) != (size_t) -1) ++ if (__glibc_objsize0 (__buf) != (size_t) -1) + { + if (!__builtin_constant_p (__n)) +- return __recv_chk (__fd, __buf, __n, __bos0 (__buf), __flags); ++ return __recv_chk (__fd, __buf, __n, __glibc_objsize0 (__buf), ++ __flags); + +- if (__n > __bos0 (__buf)) +- return __recv_chk_warn (__fd, __buf, __n, __bos0 (__buf), __flags); ++ if (__n > __glibc_objsize0 (__buf)) ++ return __recv_chk_warn (__fd, __buf, __n, __glibc_objsize0 (__buf), ++ __flags); + } + return __recv_alias (__fd, __buf, __n, __flags); + } +@@ -64,14 +66,14 @@ __fortify_function ssize_t + recvfrom (int __fd, void *__restrict __buf, size_t __n, int __flags, + __SOCKADDR_ARG __addr, socklen_t *__restrict __addr_len) + { +- if (__bos0 (__buf) != (size_t) -1) ++ if (__glibc_objsize0 (__buf) != (size_t) -1) + { + if (!__builtin_constant_p (__n)) +- return __recvfrom_chk (__fd, __buf, __n, __bos0 (__buf), __flags, +- __addr, __addr_len); +- if (__n > __bos0 (__buf)) +- return __recvfrom_chk_warn (__fd, __buf, __n, __bos0 (__buf), __flags, +- __addr, __addr_len); ++ return __recvfrom_chk (__fd, __buf, __n, __glibc_objsize0 (__buf), ++ __flags, __addr, __addr_len); ++ if (__n > __glibc_objsize0 (__buf)) ++ return __recvfrom_chk_warn (__fd, __buf, __n, __glibc_objsize0 (__buf), ++ __flags, __addr, __addr_len); + } + return __recvfrom_alias (__fd, __buf, __n, __flags, __addr, __addr_len); + } +diff --git a/stdlib/bits/stdlib.h b/stdlib/bits/stdlib.h +index 53c379b99ae9d5fe..5e4114ded33f2033 100644 +--- a/stdlib/bits/stdlib.h ++++ b/stdlib/bits/stdlib.h +@@ -36,13 +36,14 @@ extern char *__REDIRECT_NTH (__realpath_chk_warn, + __fortify_function __wur char * + __NTH (realpath (const char *__restrict __name, char *__restrict __resolved)) + { +- if (__bos (__resolved) != (size_t) -1) ++ if (__glibc_objsize (__resolved) != (size_t) -1) + { + #if defined _LIBC_LIMITS_H_ && defined PATH_MAX +- if (__bos (__resolved) < PATH_MAX) +- return __realpath_chk_warn (__name, __resolved, __bos (__resolved)); ++ if (__glibc_objsize (__resolved) < PATH_MAX) ++ return __realpath_chk_warn (__name, __resolved, ++ __glibc_objsize (__resolved)); + #endif +- return __realpath_chk (__name, __resolved, __bos (__resolved)); ++ return __realpath_chk (__name, __resolved, __glibc_objsize (__resolved)); + } + + return __realpath_alias (__name, __resolved); +@@ -63,12 +64,14 @@ extern int __REDIRECT_NTH (__ptsname_r_chk_warn, + __fortify_function int + __NTH (ptsname_r (int __fd, char *__buf, size_t __buflen)) + { +- if (__bos (__buf) != (size_t) -1) ++ if (__glibc_objsize (__buf) != (size_t) -1) + { + if (!__builtin_constant_p (__buflen)) +- return __ptsname_r_chk (__fd, __buf, __buflen, __bos (__buf)); +- if (__buflen > __bos (__buf)) +- return __ptsname_r_chk_warn (__fd, __buf, __buflen, __bos (__buf)); ++ return __ptsname_r_chk (__fd, __buf, __buflen, ++ __glibc_objsize (__buf)); ++ if (__buflen > __glibc_objsize (__buf)) ++ return __ptsname_r_chk_warn (__fd, __buf, __buflen, ++ __glibc_objsize (__buf)); + } + return __ptsname_r_alias (__fd, __buf, __buflen); + } +@@ -89,8 +92,9 @@ __NTH (wctomb (char *__s, wchar_t __wchar)) + #if defined MB_LEN_MAX && MB_LEN_MAX != __STDLIB_MB_LEN_MAX + # error "Assumed value of MB_LEN_MAX wrong" + #endif +- if (__bos (__s) != (size_t) -1 && __STDLIB_MB_LEN_MAX > __bos (__s)) +- return __wctomb_chk (__s, __wchar, __bos (__s)); ++ if (__glibc_objsize (__s) != (size_t) -1 ++ && __STDLIB_MB_LEN_MAX > __glibc_objsize (__s)) ++ return __wctomb_chk (__s, __wchar, __glibc_objsize (__s)); + return __wctomb_alias (__s, __wchar); + } + +@@ -113,15 +117,16 @@ __fortify_function size_t + __NTH (mbstowcs (wchar_t *__restrict __dst, const char *__restrict __src, + size_t __len)) + { +- if (__bos (__dst) != (size_t) -1) ++ if (__glibc_objsize (__dst) != (size_t) -1) + { + if (!__builtin_constant_p (__len)) + return __mbstowcs_chk (__dst, __src, __len, +- __bos (__dst) / sizeof (wchar_t)); ++ __glibc_objsize (__dst) / sizeof (wchar_t)); + +- if (__len > __bos (__dst) / sizeof (wchar_t)) ++ if (__len > __glibc_objsize (__dst) / sizeof (wchar_t)) + return __mbstowcs_chk_warn (__dst, __src, __len, +- __bos (__dst) / sizeof (wchar_t)); ++ (__glibc_objsize (__dst) ++ / sizeof (wchar_t))); + } + return __mbstowcs_alias (__dst, __src, __len); + } +@@ -144,12 +149,13 @@ __fortify_function size_t + __NTH (wcstombs (char *__restrict __dst, const wchar_t *__restrict __src, + size_t __len)) + { +- if (__bos (__dst) != (size_t) -1) ++ if (__glibc_objsize (__dst) != (size_t) -1) + { + if (!__builtin_constant_p (__len)) +- return __wcstombs_chk (__dst, __src, __len, __bos (__dst)); +- if (__len > __bos (__dst)) +- return __wcstombs_chk_warn (__dst, __src, __len, __bos (__dst)); ++ return __wcstombs_chk (__dst, __src, __len, __glibc_objsize (__dst)); ++ if (__len > __glibc_objsize (__dst)) ++ return __wcstombs_chk_warn (__dst, __src, __len, ++ __glibc_objsize (__dst)); + } + return __wcstombs_alias (__dst, __src, __len); + } +diff --git a/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h +index d62b86de3e288d53..838ba877ee4b4afe 100644 +--- a/wcsmbs/bits/wchar2.h ++++ b/wcsmbs/bits/wchar2.h +@@ -39,15 +39,15 @@ __fortify_function wchar_t * + __NTH (wmemcpy (wchar_t *__restrict __s1, const wchar_t *__restrict __s2, + size_t __n)) + { +- if (__bos0 (__s1) != (size_t) -1) ++ if (__glibc_objsize0 (__s1) != (size_t) -1) + { + if (!__builtin_constant_p (__n)) + return __wmemcpy_chk (__s1, __s2, __n, +- __bos0 (__s1) / sizeof (wchar_t)); ++ __glibc_objsize0 (__s1) / sizeof (wchar_t)); + +- if (__n > __bos0 (__s1) / sizeof (wchar_t)) ++ if (__n > __glibc_objsize0 (__s1) / sizeof (wchar_t)) + return __wmemcpy_chk_warn (__s1, __s2, __n, +- __bos0 (__s1) / sizeof (wchar_t)); ++ __glibc_objsize0 (__s1) / sizeof (wchar_t)); + } + return __wmemcpy_alias (__s1, __s2, __n); + } +@@ -67,15 +67,16 @@ extern wchar_t *__REDIRECT_NTH (__wmemmove_chk_warn, + __fortify_function wchar_t * + __NTH (wmemmove (wchar_t *__s1, const wchar_t *__s2, size_t __n)) + { +- if (__bos0 (__s1) != (size_t) -1) ++ if (__glibc_objsize0 (__s1) != (size_t) -1) + { + if (!__builtin_constant_p (__n)) + return __wmemmove_chk (__s1, __s2, __n, +- __bos0 (__s1) / sizeof (wchar_t)); ++ __glibc_objsize0 (__s1) / sizeof (wchar_t)); + +- if (__n > __bos0 (__s1) / sizeof (wchar_t)) ++ if (__n > __glibc_objsize0 (__s1) / sizeof (wchar_t)) + return __wmemmove_chk_warn (__s1, __s2, __n, +- __bos0 (__s1) / sizeof (wchar_t)); ++ (__glibc_objsize0 (__s1) ++ / sizeof (wchar_t))); + } + return __wmemmove_alias (__s1, __s2, __n); + } +@@ -100,15 +101,16 @@ __fortify_function wchar_t * + __NTH (wmempcpy (wchar_t *__restrict __s1, const wchar_t *__restrict __s2, + size_t __n)) + { +- if (__bos0 (__s1) != (size_t) -1) ++ if (__glibc_objsize0 (__s1) != (size_t) -1) + { + if (!__builtin_constant_p (__n)) + return __wmempcpy_chk (__s1, __s2, __n, +- __bos0 (__s1) / sizeof (wchar_t)); ++ __glibc_objsize0 (__s1) / sizeof (wchar_t)); + +- if (__n > __bos0 (__s1) / sizeof (wchar_t)) ++ if (__n > __glibc_objsize0 (__s1) / sizeof (wchar_t)) + return __wmempcpy_chk_warn (__s1, __s2, __n, +- __bos0 (__s1) / sizeof (wchar_t)); ++ (__glibc_objsize0 (__s1) ++ / sizeof (wchar_t))); + } + return __wmempcpy_alias (__s1, __s2, __n); + } +@@ -128,14 +130,15 @@ extern wchar_t *__REDIRECT_NTH (__wmemset_chk_warn, + __fortify_function wchar_t * + __NTH (wmemset (wchar_t *__s, wchar_t __c, size_t __n)) + { +- if (__bos0 (__s) != (size_t) -1) ++ if (__glibc_objsize0 (__s) != (size_t) -1) + { + if (!__builtin_constant_p (__n)) +- return __wmemset_chk (__s, __c, __n, __bos0 (__s) / sizeof (wchar_t)); ++ return __wmemset_chk (__s, __c, __n, ++ __glibc_objsize0 (__s) / sizeof (wchar_t)); + +- if (__n > __bos0 (__s) / sizeof (wchar_t)) ++ if (__n > __glibc_objsize0 (__s) / sizeof (wchar_t)) + return __wmemset_chk_warn (__s, __c, __n, +- __bos0 (__s) / sizeof (wchar_t)); ++ __glibc_objsize0 (__s) / sizeof (wchar_t)); + } + return __wmemset_alias (__s, __c, __n); + } +@@ -151,8 +154,9 @@ extern wchar_t *__REDIRECT_NTH (__wcscpy_alias, + __fortify_function wchar_t * + __NTH (wcscpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src)) + { +- if (__bos (__dest) != (size_t) -1) +- return __wcscpy_chk (__dest, __src, __bos (__dest) / sizeof (wchar_t)); ++ if (__glibc_objsize (__dest) != (size_t) -1) ++ return __wcscpy_chk (__dest, __src, ++ __glibc_objsize (__dest) / sizeof (wchar_t)); + return __wcscpy_alias (__dest, __src); + } + +@@ -167,8 +171,9 @@ extern wchar_t *__REDIRECT_NTH (__wcpcpy_alias, + __fortify_function wchar_t * + __NTH (wcpcpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src)) + { +- if (__bos (__dest) != (size_t) -1) +- return __wcpcpy_chk (__dest, __src, __bos (__dest) / sizeof (wchar_t)); ++ if (__glibc_objsize (__dest) != (size_t) -1) ++ return __wcpcpy_chk (__dest, __src, ++ __glibc_objsize (__dest) / sizeof (wchar_t)); + return __wcpcpy_alias (__dest, __src); + } + +@@ -191,14 +196,15 @@ __fortify_function wchar_t * + __NTH (wcsncpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src, + size_t __n)) + { +- if (__bos (__dest) != (size_t) -1) ++ if (__glibc_objsize (__dest) != (size_t) -1) + { + if (!__builtin_constant_p (__n)) + return __wcsncpy_chk (__dest, __src, __n, +- __bos (__dest) / sizeof (wchar_t)); +- if (__n > __bos (__dest) / sizeof (wchar_t)) ++ __glibc_objsize (__dest) / sizeof (wchar_t)); ++ if (__n > __glibc_objsize (__dest) / sizeof (wchar_t)) + return __wcsncpy_chk_warn (__dest, __src, __n, +- __bos (__dest) / sizeof (wchar_t)); ++ (__glibc_objsize (__dest) ++ / sizeof (wchar_t))); + } + return __wcsncpy_alias (__dest, __src, __n); + } +@@ -222,14 +228,15 @@ __fortify_function wchar_t * + __NTH (wcpncpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src, + size_t __n)) + { +- if (__bos (__dest) != (size_t) -1) ++ if (__glibc_objsize (__dest) != (size_t) -1) + { + if (!__builtin_constant_p (__n)) + return __wcpncpy_chk (__dest, __src, __n, +- __bos (__dest) / sizeof (wchar_t)); +- if (__n > __bos (__dest) / sizeof (wchar_t)) ++ __glibc_objsize (__dest) / sizeof (wchar_t)); ++ if (__n > __glibc_objsize (__dest) / sizeof (wchar_t)) + return __wcpncpy_chk_warn (__dest, __src, __n, +- __bos (__dest) / sizeof (wchar_t)); ++ (__glibc_objsize (__dest) ++ / sizeof (wchar_t))); + } + return __wcpncpy_alias (__dest, __src, __n); + } +@@ -245,8 +252,9 @@ extern wchar_t *__REDIRECT_NTH (__wcscat_alias, + __fortify_function wchar_t * + __NTH (wcscat (wchar_t *__restrict __dest, const wchar_t *__restrict __src)) + { +- if (__bos (__dest) != (size_t) -1) +- return __wcscat_chk (__dest, __src, __bos (__dest) / sizeof (wchar_t)); ++ if (__glibc_objsize (__dest) != (size_t) -1) ++ return __wcscat_chk (__dest, __src, ++ __glibc_objsize (__dest) / sizeof (wchar_t)); + return __wcscat_alias (__dest, __src); + } + +@@ -263,9 +271,9 @@ __fortify_function wchar_t * + __NTH (wcsncat (wchar_t *__restrict __dest, const wchar_t *__restrict __src, + size_t __n)) + { +- if (__bos (__dest) != (size_t) -1) ++ if (__glibc_objsize (__dest) != (size_t) -1) + return __wcsncat_chk (__dest, __src, __n, +- __bos (__dest) / sizeof (wchar_t)); ++ __glibc_objsize (__dest) / sizeof (wchar_t)); + return __wcsncat_alias (__dest, __src, __n); + } + +@@ -285,18 +293,18 @@ __fortify_function int + __NTH (swprintf (wchar_t *__restrict __s, size_t __n, + const wchar_t *__restrict __fmt, ...)) + { +- if (__bos (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1) ++ if (__glibc_objsize (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1) + return __swprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, +- __bos (__s) / sizeof (wchar_t), ++ __glibc_objsize (__s) / sizeof (wchar_t), + __fmt, __va_arg_pack ()); + return __swprintf_alias (__s, __n, __fmt, __va_arg_pack ()); + } + #elif !defined __cplusplus + /* XXX We might want to have support in gcc for swprintf. */ + # define swprintf(s, n, ...) \ +- (__bos (s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1 \ ++ (__glibc_objsize (s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1 \ + ? __swprintf_chk (s, n, __USE_FORTIFY_LEVEL - 1, \ +- __bos (s) / sizeof (wchar_t), __VA_ARGS__) \ ++ __glibc_objsize (s) / sizeof (wchar_t), __VA_ARGS__) \ + : swprintf (s, n, __VA_ARGS__)) + #endif + +@@ -315,9 +323,10 @@ __fortify_function int + __NTH (vswprintf (wchar_t *__restrict __s, size_t __n, + const wchar_t *__restrict __fmt, __gnuc_va_list __ap)) + { +- if (__bos (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1) ++ if (__glibc_objsize (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1) + return __vswprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, +- __bos (__s) / sizeof (wchar_t), __fmt, __ap); ++ __glibc_objsize (__s) / sizeof (wchar_t), __fmt, ++ __ap); + return __vswprintf_alias (__s, __n, __fmt, __ap); + } + +@@ -383,14 +392,15 @@ extern wchar_t *__REDIRECT (__fgetws_chk_warn, + __fortify_function __wur wchar_t * + fgetws (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream) + { +- if (__bos (__s) != (size_t) -1) ++ if (__glibc_objsize (__s) != (size_t) -1) + { + if (!__builtin_constant_p (__n) || __n <= 0) +- return __fgetws_chk (__s, __bos (__s) / sizeof (wchar_t), ++ return __fgetws_chk (__s, __glibc_objsize (__s) / sizeof (wchar_t), + __n, __stream); + +- if ((size_t) __n > __bos (__s) / sizeof (wchar_t)) +- return __fgetws_chk_warn (__s, __bos (__s) / sizeof (wchar_t), ++ if ((size_t) __n > __glibc_objsize (__s) / sizeof (wchar_t)) ++ return __fgetws_chk_warn (__s, ++ __glibc_objsize (__s) / sizeof (wchar_t), + __n, __stream); + } + return __fgetws_alias (__s, __n, __stream); +@@ -414,14 +424,17 @@ extern wchar_t *__REDIRECT (__fgetws_unlocked_chk_warn, + __fortify_function __wur wchar_t * + fgetws_unlocked (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream) + { +- if (__bos (__s) != (size_t) -1) ++ if (__glibc_objsize (__s) != (size_t) -1) + { + if (!__builtin_constant_p (__n) || __n <= 0) +- return __fgetws_unlocked_chk (__s, __bos (__s) / sizeof (wchar_t), ++ return __fgetws_unlocked_chk (__s, ++ __glibc_objsize (__s) / sizeof (wchar_t), + __n, __stream); + +- if ((size_t) __n > __bos (__s) / sizeof (wchar_t)) +- return __fgetws_unlocked_chk_warn (__s, __bos (__s) / sizeof (wchar_t), ++ if ((size_t) __n > __glibc_objsize (__s) / sizeof (wchar_t)) ++ return __fgetws_unlocked_chk_warn (__s, ++ (__glibc_objsize (__s) ++ / sizeof (wchar_t)), + __n, __stream); + } + return __fgetws_unlocked_alias (__s, __n, __stream); +@@ -447,8 +460,9 @@ __NTH (wcrtomb (char *__restrict __s, wchar_t __wchar, + #if defined MB_LEN_MAX && MB_LEN_MAX != __WCHAR_MB_LEN_MAX + # error "Assumed value of MB_LEN_MAX wrong" + #endif +- if (__bos (__s) != (size_t) -1 && __WCHAR_MB_LEN_MAX > __bos (__s)) +- return __wcrtomb_chk (__s, __wchar, __ps, __bos (__s)); ++ if (__glibc_objsize (__s) != (size_t) -1 ++ && __WCHAR_MB_LEN_MAX > __glibc_objsize (__s)) ++ return __wcrtomb_chk (__s, __wchar, __ps, __glibc_objsize (__s)); + return __wcrtomb_alias (__s, __wchar, __ps); + } + +@@ -474,15 +488,16 @@ __fortify_function size_t + __NTH (mbsrtowcs (wchar_t *__restrict __dst, const char **__restrict __src, + size_t __len, mbstate_t *__restrict __ps)) + { +- if (__bos (__dst) != (size_t) -1) ++ if (__glibc_objsize (__dst) != (size_t) -1) + { + if (!__builtin_constant_p (__len)) + return __mbsrtowcs_chk (__dst, __src, __len, __ps, +- __bos (__dst) / sizeof (wchar_t)); ++ __glibc_objsize (__dst) / sizeof (wchar_t)); + +- if (__len > __bos (__dst) / sizeof (wchar_t)) ++ if (__len > __glibc_objsize (__dst) / sizeof (wchar_t)) + return __mbsrtowcs_chk_warn (__dst, __src, __len, __ps, +- __bos (__dst) / sizeof (wchar_t)); ++ (__glibc_objsize (__dst) ++ / sizeof (wchar_t))); + } + return __mbsrtowcs_alias (__dst, __src, __len, __ps); + } +@@ -508,13 +523,15 @@ __fortify_function size_t + __NTH (wcsrtombs (char *__restrict __dst, const wchar_t **__restrict __src, + size_t __len, mbstate_t *__restrict __ps)) + { +- if (__bos (__dst) != (size_t) -1) ++ if (__glibc_objsize (__dst) != (size_t) -1) + { + if (!__builtin_constant_p (__len)) +- return __wcsrtombs_chk (__dst, __src, __len, __ps, __bos (__dst)); ++ return __wcsrtombs_chk (__dst, __src, __len, __ps, ++ __glibc_objsize (__dst)); + +- if (__len > __bos (__dst)) +- return __wcsrtombs_chk_warn (__dst, __src, __len, __ps, __bos (__dst)); ++ if (__len > __glibc_objsize (__dst)) ++ return __wcsrtombs_chk_warn (__dst, __src, __len, __ps, ++ __glibc_objsize (__dst)); + } + return __wcsrtombs_alias (__dst, __src, __len, __ps); + } +@@ -542,15 +559,16 @@ __fortify_function size_t + __NTH (mbsnrtowcs (wchar_t *__restrict __dst, const char **__restrict __src, + size_t __nmc, size_t __len, mbstate_t *__restrict __ps)) + { +- if (__bos (__dst) != (size_t) -1) ++ if (__glibc_objsize (__dst) != (size_t) -1) + { + if (!__builtin_constant_p (__len)) + return __mbsnrtowcs_chk (__dst, __src, __nmc, __len, __ps, +- __bos (__dst) / sizeof (wchar_t)); ++ __glibc_objsize (__dst) / sizeof (wchar_t)); + +- if (__len > __bos (__dst) / sizeof (wchar_t)) ++ if (__len > __glibc_objsize (__dst) / sizeof (wchar_t)) + return __mbsnrtowcs_chk_warn (__dst, __src, __nmc, __len, __ps, +- __bos (__dst) / sizeof (wchar_t)); ++ (__glibc_objsize (__dst) ++ / sizeof (wchar_t))); + } + return __mbsnrtowcs_alias (__dst, __src, __nmc, __len, __ps); + } +@@ -578,15 +596,15 @@ __fortify_function size_t + __NTH (wcsnrtombs (char *__restrict __dst, const wchar_t **__restrict __src, + size_t __nwc, size_t __len, mbstate_t *__restrict __ps)) + { +- if (__bos (__dst) != (size_t) -1) ++ if (__glibc_objsize (__dst) != (size_t) -1) + { + if (!__builtin_constant_p (__len)) + return __wcsnrtombs_chk (__dst, __src, __nwc, __len, __ps, +- __bos (__dst)); ++ __glibc_objsize (__dst)); + +- if (__len > __bos (__dst)) ++ if (__len > __glibc_objsize (__dst)) + return __wcsnrtombs_chk_warn (__dst, __src, __nwc, __len, __ps, +- __bos (__dst)); ++ __glibc_objsize (__dst)); + } + return __wcsnrtombs_alias (__dst, __src, __nwc, __len, __ps); + } diff --git a/SOURCES/glibc-rh2033684-6.patch b/SOURCES/glibc-rh2033684-6.patch new file mode 100644 index 0000000..b183d70 --- /dev/null +++ b/SOURCES/glibc-rh2033684-6.patch @@ -0,0 +1,1037 @@ +commit a643f60c53876be0d57b4b7373770e6cb356fd13 +Author: Siddhesh Poyarekar +Date: Wed Oct 20 18:12:41 2021 +0530 + + Make sure that the fortified function conditionals are constant + + In _FORTIFY_SOURCE=3, the size expression may be non-constant, + resulting in branches in the inline functions remaining intact and + causing a tiny overhead. Clang (and in future, gcc) make sure that + the -1 case is always safe, i.e. any comparison of the generated + expression with (size_t)-1 is always false so that bit is taken care + of. The rest is avoidable since we want the _chk variant whenever we + have a size expression and it's not -1. + + Rework the conditionals in a uniform way to clearly indicate two + conditions at compile time: + + - Either the size is unknown (-1) or we know at compile time that the + operation length is less than the object size. We can call the + original function in this case. It could be that either the length, + object size or both are non-constant, but the compiler, through + range analysis, is able to fold the *comparison* to a constant. + + - The size and length are known and the compiler can see at compile + time that operation length > object size. This is valid grounds for + a warning at compile time, followed by emitting the _chk variant. + + For everything else, emit the _chk variant. + + This simplifies most of the fortified function implementations and at + the same time, ensures that only one call from _chk or the regular + function is emitted. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Adhemerval Zanella + +diff --git a/io/bits/poll2.h b/io/bits/poll2.h +index f47fd9ad0945234f..6f4dae77e5e2d0d3 100644 +--- a/io/bits/poll2.h ++++ b/io/bits/poll2.h +@@ -35,16 +35,9 @@ extern int __REDIRECT (__poll_chk_warn, (struct pollfd *__fds, nfds_t __nfds, + __fortify_function int + poll (struct pollfd *__fds, nfds_t __nfds, int __timeout) + { +- if (__glibc_objsize (__fds) != (__SIZE_TYPE__) -1) +- { +- if (! __builtin_constant_p (__nfds)) +- return __poll_chk (__fds, __nfds, __timeout, __glibc_objsize (__fds)); +- else if (__glibc_objsize (__fds) / sizeof (*__fds) < __nfds) +- return __poll_chk_warn (__fds, __nfds, __timeout, +- __glibc_objsize (__fds)); +- } +- +- return __poll_alias (__fds, __nfds, __timeout); ++ return __glibc_fortify (poll, __nfds, sizeof (*__fds), ++ __glibc_objsize (__fds), ++ __fds, __nfds, __timeout); + } + + +@@ -66,17 +59,9 @@ __fortify_function int + ppoll (struct pollfd *__fds, nfds_t __nfds, const struct timespec *__timeout, + const __sigset_t *__ss) + { +- if (__glibc_objsize (__fds) != (__SIZE_TYPE__) -1) +- { +- if (! __builtin_constant_p (__nfds)) +- return __ppoll_chk (__fds, __nfds, __timeout, __ss, +- __glibc_objsize (__fds)); +- else if (__glibc_objsize (__fds) / sizeof (*__fds) < __nfds) +- return __ppoll_chk_warn (__fds, __nfds, __timeout, __ss, +- __glibc_objsize (__fds)); +- } +- +- return __ppoll_alias (__fds, __nfds, __timeout, __ss); ++ return __glibc_fortify (ppoll, __nfds, sizeof (*__fds), ++ __glibc_objsize (__fds), ++ __fds, __nfds, __timeout, __ss); + } + #endif + +diff --git a/libio/bits/stdio2.h b/libio/bits/stdio2.h +index 2cd69f44cfadfc9f..4630fe0256b1a562 100644 +--- a/libio/bits/stdio2.h ++++ b/libio/bits/stdio2.h +@@ -256,15 +256,12 @@ extern char *__REDIRECT (__fgets_chk_warn, + __fortify_function __wur char * + fgets (char *__restrict __s, int __n, FILE *__restrict __stream) + { +- if (__glibc_objsize (__s) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n) || __n <= 0) +- return __fgets_chk (__s, __glibc_objsize (__s), __n, __stream); +- +- if ((size_t) __n > __glibc_objsize (__s)) +- return __fgets_chk_warn (__s, __glibc_objsize (__s), __n, __stream); +- } +- return __fgets_alias (__s, __n, __stream); ++ size_t sz = __glibc_objsize (__s); ++ if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz)) ++ return __fgets_alias (__s, __n, __stream); ++ if (__glibc_unsafe_len (__n, sizeof (char), sz)) ++ return __fgets_chk_warn (__s, sz, __n, __stream); ++ return __fgets_chk (__s, sz, __n, __stream); + } + + extern size_t __fread_chk (void *__restrict __ptr, size_t __ptrlen, +@@ -286,19 +283,12 @@ __fortify_function __wur size_t + fread (void *__restrict __ptr, size_t __size, size_t __n, + FILE *__restrict __stream) + { +- if (__glibc_objsize0 (__ptr) != (size_t) -1) +- { +- if (!__builtin_constant_p (__size) +- || !__builtin_constant_p (__n) +- || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2))) +- return __fread_chk (__ptr, __glibc_objsize0 (__ptr), __size, __n, +- __stream); +- +- if (__size * __n > __glibc_objsize0 (__ptr)) +- return __fread_chk_warn (__ptr, __glibc_objsize0 (__ptr), __size, __n, +- __stream); +- } +- return __fread_alias (__ptr, __size, __n, __stream); ++ size_t sz = __glibc_objsize0 (__ptr); ++ if (__glibc_safe_or_unknown_len (__n, __size, sz)) ++ return __fread_alias (__ptr, __size, __n, __stream); ++ if (__glibc_unsafe_len (__n, __size, sz)) ++ return __fread_chk_warn (__ptr, sz, __size, __n, __stream); ++ return __fread_chk (__ptr, sz, __size, __n, __stream); + } + + #ifdef __USE_GNU +@@ -316,17 +306,12 @@ extern char *__REDIRECT (__fgets_unlocked_chk_warn, + __fortify_function __wur char * + fgets_unlocked (char *__restrict __s, int __n, FILE *__restrict __stream) + { +- if (__glibc_objsize (__s) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n) || __n <= 0) +- return __fgets_unlocked_chk (__s, __glibc_objsize (__s), __n, +- __stream); +- +- if ((size_t) __n > __glibc_objsize (__s)) +- return __fgets_unlocked_chk_warn (__s, __glibc_objsize (__s), __n, +- __stream); +- } +- return __fgets_unlocked_alias (__s, __n, __stream); ++ size_t sz = __glibc_objsize (__s); ++ if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz)) ++ return __fgets_unlocked_alias (__s, __n, __stream); ++ if (__glibc_unsafe_len (__n, sizeof (char), sz)) ++ return __fgets_unlocked_chk_warn (__s, sz, __n, __stream); ++ return __fgets_unlocked_chk (__s, sz, __n, __stream); + } + #endif + +@@ -351,41 +336,36 @@ __fortify_function __wur size_t + fread_unlocked (void *__restrict __ptr, size_t __size, size_t __n, + FILE *__restrict __stream) + { +- if (__glibc_objsize0 (__ptr) != (size_t) -1) ++ size_t sz = __glibc_objsize0 (__ptr); ++ if (__glibc_safe_or_unknown_len (__n, __size, sz)) + { +- if (!__builtin_constant_p (__size) +- || !__builtin_constant_p (__n) +- || (__size | __n) >= (((size_t) 1) << (8 * sizeof (size_t) / 2))) +- return __fread_unlocked_chk (__ptr, __glibc_objsize0 (__ptr), __size, +- __n, __stream); +- +- if (__size * __n > __glibc_objsize0 (__ptr)) +- return __fread_unlocked_chk_warn (__ptr, __glibc_objsize0 (__ptr), +- __size, __n, __stream); +- } +- + # ifdef __USE_EXTERN_INLINES +- if (__builtin_constant_p (__size) +- && __builtin_constant_p (__n) +- && (__size | __n) < (((size_t) 1) << (8 * sizeof (size_t) / 2)) +- && __size * __n <= 8) +- { +- size_t __cnt = __size * __n; +- char *__cptr = (char *) __ptr; +- if (__cnt == 0) +- return 0; +- +- for (; __cnt > 0; --__cnt) ++ if (__builtin_constant_p (__size) ++ && __builtin_constant_p (__n) ++ && (__size | __n) < (((size_t) 1) << (8 * sizeof (size_t) / 2)) ++ && __size * __n <= 8) + { +- int __c = getc_unlocked (__stream); +- if (__c == EOF) +- break; +- *__cptr++ = __c; ++ size_t __cnt = __size * __n; ++ char *__cptr = (char *) __ptr; ++ if (__cnt == 0) ++ return 0; ++ ++ for (; __cnt > 0; --__cnt) ++ { ++ int __c = getc_unlocked (__stream); ++ if (__c == EOF) ++ break; ++ *__cptr++ = __c; ++ } ++ return (__cptr - (char *) __ptr) / __size; + } +- return (__cptr - (char *) __ptr) / __size; +- } + # endif +- return __fread_unlocked_alias (__ptr, __size, __n, __stream); ++ return __fread_unlocked_alias (__ptr, __size, __n, __stream); ++ } ++ if (__glibc_unsafe_len (__n, __size, sz)) ++ return __fread_unlocked_chk_warn (__ptr, sz, __size, __n, __stream); ++ return __fread_unlocked_chk (__ptr, sz, __size, __n, __stream); ++ + } + #endif + +diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h +index 1e39307b0ebcf38f..17b84a2e6c69d961 100644 +--- a/misc/sys/cdefs.h ++++ b/misc/sys/cdefs.h +@@ -132,6 +132,53 @@ + # define __glibc_objsize(__o) __bos (__o) + #endif + ++/* Compile time conditions to choose between the regular, _chk and _chk_warn ++ variants. These conditions should get evaluated to constant and optimized ++ away. */ ++ ++#define __glibc_safe_len_cond(__l, __s, __osz) ((__l) <= (__osz) / (__s)) ++#define __glibc_unsigned_or_positive(__l) \ ++ ((__typeof (__l)) 0 < (__typeof (__l)) -1 \ ++ || (__builtin_constant_p (__l) && (__l) > 0)) ++ ++/* Length is known to be safe at compile time if the __L * __S <= __OBJSZ ++ condition can be folded to a constant and if it is true. The -1 check is ++ redundant because since it implies that __glibc_safe_len_cond is true. */ ++#define __glibc_safe_or_unknown_len(__l, __s, __osz) \ ++ (__glibc_unsigned_or_positive (__l) \ ++ && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \ ++ __s, __osz)) \ ++ && __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz)) ++ ++/* Conversely, we know at compile time that the length is safe if the ++ __L * __S <= __OBJSZ condition can be folded to a constant and if it is ++ false. */ ++#define __glibc_unsafe_len(__l, __s, __osz) \ ++ (__glibc_unsigned_or_positive (__l) \ ++ && __builtin_constant_p (__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), \ ++ __s, __osz)) \ ++ && !__glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz)) ++ ++/* Fortify function f. __f_alias, __f_chk and __f_chk_warn must be ++ declared. */ ++ ++#define __glibc_fortify(f, __l, __s, __osz, ...) \ ++ (__glibc_safe_or_unknown_len (__l, __s, __osz) \ ++ ? __ ## f ## _alias (__VA_ARGS__) \ ++ : (__glibc_unsafe_len (__l, __s, __osz) \ ++ ? __ ## f ## _chk_warn (__VA_ARGS__, __osz) \ ++ : __ ## f ## _chk (__VA_ARGS__, __osz))) \ ++ ++/* Fortify function f, where object size argument passed to f is the number of ++ elements and not total size. */ ++ ++#define __glibc_fortify_n(f, __l, __s, __osz, ...) \ ++ (__glibc_safe_or_unknown_len (__l, __s, __osz) \ ++ ? __ ## f ## _alias (__VA_ARGS__) \ ++ : (__glibc_unsafe_len (__l, __s, __osz) \ ++ ? __ ## f ## _chk_warn (__VA_ARGS__, (__osz) / (__s)) \ ++ : __ ## f ## _chk (__VA_ARGS__, (__osz) / (__s)))) \ ++ + #if __GNUC_PREREQ (4,3) + # define __warndecl(name, msg) \ + extern void name (void) __attribute__((__warning__ (msg))) +diff --git a/posix/bits/unistd.h b/posix/bits/unistd.h +index a0c4dcfe9c61a7b8..a456d1723547db70 100644 +--- a/posix/bits/unistd.h ++++ b/posix/bits/unistd.h +@@ -33,16 +33,9 @@ extern ssize_t __REDIRECT (__read_chk_warn, + __fortify_function __wur ssize_t + read (int __fd, void *__buf, size_t __nbytes) + { +- if (__glibc_objsize0 (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__nbytes)) +- return __read_chk (__fd, __buf, __nbytes, __glibc_objsize0 (__buf)); +- +- if (__nbytes > __glibc_objsize0 (__buf)) +- return __read_chk_warn (__fd, __buf, __nbytes, +- __glibc_objsize0 (__buf)); +- } +- return __read_alias (__fd, __buf, __nbytes); ++ return __glibc_fortify (read, __nbytes, sizeof (char), ++ __glibc_objsize0 (__buf), ++ __fd, __buf, __nbytes); + } + + #ifdef __USE_UNIX98 +@@ -72,34 +65,17 @@ extern ssize_t __REDIRECT (__pread64_chk_warn, + __fortify_function __wur ssize_t + pread (int __fd, void *__buf, size_t __nbytes, __off_t __offset) + { +- if (__glibc_objsize0 (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__nbytes)) +- return __pread_chk (__fd, __buf, __nbytes, __offset, +- __glibc_objsize0 (__buf)); +- +- if ( __nbytes > __glibc_objsize0 (__buf)) +- return __pread_chk_warn (__fd, __buf, __nbytes, __offset, +- __glibc_objsize0 (__buf)); +- } +- return __pread_alias (__fd, __buf, __nbytes, __offset); ++ return __glibc_fortify (pread, __nbytes, sizeof (char), ++ __glibc_objsize0 (__buf), ++ __fd, __buf, __nbytes, __offset); + } + # else + __fortify_function __wur ssize_t + pread (int __fd, void *__buf, size_t __nbytes, __off64_t __offset) + { +- if (__glibc_objsize0 (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__nbytes)) +- return __pread64_chk (__fd, __buf, __nbytes, __offset, +- __glibc_objsize0 (__buf)); +- +- if ( __nbytes > __glibc_objsize0 (__buf)) +- return __pread64_chk_warn (__fd, __buf, __nbytes, __offset, +- __glibc_objsize0 (__buf)); +- } +- +- return __pread64_alias (__fd, __buf, __nbytes, __offset); ++ return __glibc_fortify (pread64, __nbytes, sizeof (char), ++ __glibc_objsize0 (__buf), ++ __fd, __buf, __nbytes, __offset); + } + # endif + +@@ -107,18 +83,9 @@ pread (int __fd, void *__buf, size_t __nbytes, __off64_t __offset) + __fortify_function __wur ssize_t + pread64 (int __fd, void *__buf, size_t __nbytes, __off64_t __offset) + { +- if (__glibc_objsize0 (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__nbytes)) +- return __pread64_chk (__fd, __buf, __nbytes, __offset, +- __glibc_objsize0 (__buf)); +- +- if ( __nbytes > __glibc_objsize0 (__buf)) +- return __pread64_chk_warn (__fd, __buf, __nbytes, __offset, +- __glibc_objsize0 (__buf)); +- } +- +- return __pread64_alias (__fd, __buf, __nbytes, __offset); ++ return __glibc_fortify (pread64, __nbytes, sizeof (char), ++ __glibc_objsize0 (__buf), ++ __fd, __buf, __nbytes, __offset); + } + # endif + #endif +@@ -143,16 +110,9 @@ __fortify_function __nonnull ((1, 2)) __wur ssize_t + __NTH (readlink (const char *__restrict __path, char *__restrict __buf, + size_t __len)) + { +- if (__glibc_objsize (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__len)) +- return __readlink_chk (__path, __buf, __len, __glibc_objsize (__buf)); +- +- if ( __len > __glibc_objsize (__buf)) +- return __readlink_chk_warn (__path, __buf, __len, +- __glibc_objsize (__buf)); +- } +- return __readlink_alias (__path, __buf, __len); ++ return __glibc_fortify (readlink, __len, sizeof (char), ++ __glibc_objsize (__buf), ++ __path, __buf, __len); + } + #endif + +@@ -178,17 +138,9 @@ __fortify_function __nonnull ((2, 3)) __wur ssize_t + __NTH (readlinkat (int __fd, const char *__restrict __path, + char *__restrict __buf, size_t __len)) + { +- if (__glibc_objsize (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__len)) +- return __readlinkat_chk (__fd, __path, __buf, __len, +- __glibc_objsize (__buf)); +- +- if (__len > __glibc_objsize (__buf)) +- return __readlinkat_chk_warn (__fd, __path, __buf, __len, +- __glibc_objsize (__buf)); +- } +- return __readlinkat_alias (__fd, __path, __buf, __len); ++ return __glibc_fortify (readlinkat, __len, sizeof (char), ++ __glibc_objsize (__buf), ++ __fd, __path, __buf, __len); + } + #endif + +@@ -205,15 +157,9 @@ extern char *__REDIRECT_NTH (__getcwd_chk_warn, + __fortify_function __wur char * + __NTH (getcwd (char *__buf, size_t __size)) + { +- if (__glibc_objsize (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__size)) +- return __getcwd_chk (__buf, __size, __glibc_objsize (__buf)); +- +- if (__size > __glibc_objsize (__buf)) +- return __getcwd_chk_warn (__buf, __size, __glibc_objsize (__buf)); +- } +- return __getcwd_alias (__buf, __size); ++ return __glibc_fortify (getcwd, __size, sizeof (char), ++ __glibc_objsize (__buf), ++ __buf, __size); + } + + #if defined __USE_MISC || defined __USE_XOPEN_EXTENDED +@@ -245,16 +191,9 @@ extern size_t __REDIRECT_NTH (__confstr_chk_warn, + __fortify_function size_t + __NTH (confstr (int __name, char *__buf, size_t __len)) + { +- if (__glibc_objsize (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__len)) +- return __confstr_chk (__name, __buf, __len, __glibc_objsize (__buf)); +- +- if (__glibc_objsize (__buf) < __len) +- return __confstr_chk_warn (__name, __buf, __len, +- __glibc_objsize (__buf)); +- } +- return __confstr_alias (__name, __buf, __len); ++ return __glibc_fortify (confstr, __len, sizeof (char), ++ __glibc_objsize (__buf), ++ __name, __buf, __len); + } + + +@@ -271,15 +210,9 @@ extern int __REDIRECT_NTH (__getgroups_chk_warn, + __fortify_function int + __NTH (getgroups (int __size, __gid_t __list[])) + { +- if (__glibc_objsize (__list) != (size_t) -1) +- { +- if (!__builtin_constant_p (__size) || __size < 0) +- return __getgroups_chk (__size, __list, __glibc_objsize (__list)); +- +- if (__size * sizeof (__gid_t) > __glibc_objsize (__list)) +- return __getgroups_chk_warn (__size, __list, __glibc_objsize (__list)); +- } +- return __getgroups_alias (__size, __list); ++ return __glibc_fortify (getgroups, __size, sizeof (__gid_t), ++ __glibc_objsize (__list), ++ __size, __list); + } + + +@@ -297,17 +230,9 @@ extern int __REDIRECT_NTH (__ttyname_r_chk_warn, + __fortify_function int + __NTH (ttyname_r (int __fd, char *__buf, size_t __buflen)) + { +- if (__glibc_objsize (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__buflen)) +- return __ttyname_r_chk (__fd, __buf, __buflen, +- __glibc_objsize (__buf)); +- +- if (__buflen > __glibc_objsize (__buf)) +- return __ttyname_r_chk_warn (__fd, __buf, __buflen, +- __glibc_objsize (__buf)); +- } +- return __ttyname_r_alias (__fd, __buf, __buflen); ++ return __glibc_fortify (ttyname_r, __buflen, sizeof (char), ++ __glibc_objsize (__buf), ++ __fd, __buf, __buflen); + } + + +@@ -325,16 +250,9 @@ extern int __REDIRECT (__getlogin_r_chk_warn, + __fortify_function int + getlogin_r (char *__buf, size_t __buflen) + { +- if (__glibc_objsize (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__buflen)) +- return __getlogin_r_chk (__buf, __buflen, __glibc_objsize (__buf)); +- +- if (__buflen > __glibc_objsize (__buf)) +- return __getlogin_r_chk_warn (__buf, __buflen, +- __glibc_objsize (__buf)); +- } +- return __getlogin_r_alias (__buf, __buflen); ++ return __glibc_fortify (getlogin_r, __buflen, sizeof (char), ++ __glibc_objsize (__buf), ++ __buf, __buflen); + } + #endif + +@@ -353,16 +271,9 @@ extern int __REDIRECT_NTH (__gethostname_chk_warn, + __fortify_function int + __NTH (gethostname (char *__buf, size_t __buflen)) + { +- if (__glibc_objsize (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__buflen)) +- return __gethostname_chk (__buf, __buflen, __glibc_objsize (__buf)); +- +- if (__buflen > __glibc_objsize (__buf)) +- return __gethostname_chk_warn (__buf, __buflen, +- __glibc_objsize (__buf)); +- } +- return __gethostname_alias (__buf, __buflen); ++ return __glibc_fortify (gethostname, __buflen, sizeof (char), ++ __glibc_objsize (__buf), ++ __buf, __buflen); + } + #endif + +@@ -383,15 +294,8 @@ extern int __REDIRECT_NTH (__getdomainname_chk_warn, + __fortify_function int + __NTH (getdomainname (char *__buf, size_t __buflen)) + { +- if (__glibc_objsize (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__buflen)) +- return __getdomainname_chk (__buf, __buflen, __glibc_objsize (__buf)); +- +- if (__buflen > __glibc_objsize (__buf)) +- return __getdomainname_chk_warn (__buf, __buflen, +- __glibc_objsize (__buf)); +- } +- return __getdomainname_alias (__buf, __buflen); ++ return __glibc_fortify (getdomainname, __buflen, sizeof (char), ++ __glibc_objsize (__buf), ++ __buf, __buflen); + } + #endif +diff --git a/socket/bits/socket2.h b/socket/bits/socket2.h +index 729e5a4cc1f4cb92..68fe5435b3b29c2a 100644 +--- a/socket/bits/socket2.h ++++ b/socket/bits/socket2.h +@@ -33,17 +33,12 @@ extern ssize_t __REDIRECT (__recv_chk_warn, + __fortify_function ssize_t + recv (int __fd, void *__buf, size_t __n, int __flags) + { +- if (__glibc_objsize0 (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n)) +- return __recv_chk (__fd, __buf, __n, __glibc_objsize0 (__buf), +- __flags); +- +- if (__n > __glibc_objsize0 (__buf)) +- return __recv_chk_warn (__fd, __buf, __n, __glibc_objsize0 (__buf), +- __flags); +- } +- return __recv_alias (__fd, __buf, __n, __flags); ++ size_t sz = __glibc_objsize0 (__buf); ++ if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz)) ++ return __recv_alias (__fd, __buf, __n, __flags); ++ if (__glibc_unsafe_len (__n, sizeof (char), sz)) ++ return __recv_chk_warn (__fd, __buf, __n, sz, __flags); ++ return __recv_chk (__fd, __buf, __n, sz, __flags); + } + + extern ssize_t __recvfrom_chk (int __fd, void *__restrict __buf, size_t __n, +@@ -66,14 +61,11 @@ __fortify_function ssize_t + recvfrom (int __fd, void *__restrict __buf, size_t __n, int __flags, + __SOCKADDR_ARG __addr, socklen_t *__restrict __addr_len) + { +- if (__glibc_objsize0 (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n)) +- return __recvfrom_chk (__fd, __buf, __n, __glibc_objsize0 (__buf), +- __flags, __addr, __addr_len); +- if (__n > __glibc_objsize0 (__buf)) +- return __recvfrom_chk_warn (__fd, __buf, __n, __glibc_objsize0 (__buf), +- __flags, __addr, __addr_len); +- } +- return __recvfrom_alias (__fd, __buf, __n, __flags, __addr, __addr_len); ++ size_t sz = __glibc_objsize0 (__buf); ++ if (__glibc_safe_or_unknown_len (__n, sizeof (char), sz)) ++ return __recvfrom_alias (__fd, __buf, __n, __flags, __addr, __addr_len); ++ if (__glibc_unsafe_len (__n, sizeof (char), sz)) ++ return __recvfrom_chk_warn (__fd, __buf, __n, sz, __flags, __addr, ++ __addr_len); ++ return __recvfrom_chk (__fd, __buf, __n, sz, __flags, __addr, __addr_len); + } +diff --git a/stdlib/bits/stdlib.h b/stdlib/bits/stdlib.h +index 5e4114ded33f2033..7ea364a276497720 100644 +--- a/stdlib/bits/stdlib.h ++++ b/stdlib/bits/stdlib.h +@@ -36,17 +36,16 @@ extern char *__REDIRECT_NTH (__realpath_chk_warn, + __fortify_function __wur char * + __NTH (realpath (const char *__restrict __name, char *__restrict __resolved)) + { +- if (__glibc_objsize (__resolved) != (size_t) -1) +- { ++ size_t sz = __glibc_objsize (__resolved); ++ ++ if (sz == (size_t) -1) ++ return __realpath_alias (__name, __resolved); ++ + #if defined _LIBC_LIMITS_H_ && defined PATH_MAX +- if (__glibc_objsize (__resolved) < PATH_MAX) +- return __realpath_chk_warn (__name, __resolved, +- __glibc_objsize (__resolved)); ++ if (__glibc_unsafe_len (sz, sizeof (char), PATH_MAX)) ++ return __realpath_chk_warn (__name, __resolved, sz); + #endif +- return __realpath_chk (__name, __resolved, __glibc_objsize (__resolved)); +- } +- +- return __realpath_alias (__name, __resolved); ++ return __realpath_chk (__name, __resolved, sz); + } + + +@@ -64,16 +63,9 @@ extern int __REDIRECT_NTH (__ptsname_r_chk_warn, + __fortify_function int + __NTH (ptsname_r (int __fd, char *__buf, size_t __buflen)) + { +- if (__glibc_objsize (__buf) != (size_t) -1) +- { +- if (!__builtin_constant_p (__buflen)) +- return __ptsname_r_chk (__fd, __buf, __buflen, +- __glibc_objsize (__buf)); +- if (__buflen > __glibc_objsize (__buf)) +- return __ptsname_r_chk_warn (__fd, __buf, __buflen, +- __glibc_objsize (__buf)); +- } +- return __ptsname_r_alias (__fd, __buf, __buflen); ++ return __glibc_fortify (ptsname_r, __buflen, sizeof (char), ++ __glibc_objsize (__buf), ++ __fd, __buf, __buflen); + } + + +@@ -117,18 +109,9 @@ __fortify_function size_t + __NTH (mbstowcs (wchar_t *__restrict __dst, const char *__restrict __src, + size_t __len)) + { +- if (__glibc_objsize (__dst) != (size_t) -1) +- { +- if (!__builtin_constant_p (__len)) +- return __mbstowcs_chk (__dst, __src, __len, +- __glibc_objsize (__dst) / sizeof (wchar_t)); +- +- if (__len > __glibc_objsize (__dst) / sizeof (wchar_t)) +- return __mbstowcs_chk_warn (__dst, __src, __len, +- (__glibc_objsize (__dst) +- / sizeof (wchar_t))); +- } +- return __mbstowcs_alias (__dst, __src, __len); ++ return __glibc_fortify_n (mbstowcs, __len, sizeof (wchar_t), ++ __glibc_objsize (__dst), ++ __dst, __src, __len); + } + + +@@ -149,13 +132,7 @@ __fortify_function size_t + __NTH (wcstombs (char *__restrict __dst, const wchar_t *__restrict __src, + size_t __len)) + { +- if (__glibc_objsize (__dst) != (size_t) -1) +- { +- if (!__builtin_constant_p (__len)) +- return __wcstombs_chk (__dst, __src, __len, __glibc_objsize (__dst)); +- if (__len > __glibc_objsize (__dst)) +- return __wcstombs_chk_warn (__dst, __src, __len, +- __glibc_objsize (__dst)); +- } +- return __wcstombs_alias (__dst, __src, __len); ++ return __glibc_fortify (wcstombs, __len, sizeof (char), ++ __glibc_objsize (__dst), ++ __dst, __src, __len); + } +diff --git a/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h +index 838ba877ee4b4afe..f82bba481981e4fb 100644 +--- a/wcsmbs/bits/wchar2.h ++++ b/wcsmbs/bits/wchar2.h +@@ -39,17 +39,9 @@ __fortify_function wchar_t * + __NTH (wmemcpy (wchar_t *__restrict __s1, const wchar_t *__restrict __s2, + size_t __n)) + { +- if (__glibc_objsize0 (__s1) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n)) +- return __wmemcpy_chk (__s1, __s2, __n, +- __glibc_objsize0 (__s1) / sizeof (wchar_t)); +- +- if (__n > __glibc_objsize0 (__s1) / sizeof (wchar_t)) +- return __wmemcpy_chk_warn (__s1, __s2, __n, +- __glibc_objsize0 (__s1) / sizeof (wchar_t)); +- } +- return __wmemcpy_alias (__s1, __s2, __n); ++ return __glibc_fortify_n (wmemcpy, __n, sizeof (wchar_t), ++ __glibc_objsize0 (__s1), ++ __s1, __s2, __n); + } + + +@@ -67,18 +59,9 @@ extern wchar_t *__REDIRECT_NTH (__wmemmove_chk_warn, + __fortify_function wchar_t * + __NTH (wmemmove (wchar_t *__s1, const wchar_t *__s2, size_t __n)) + { +- if (__glibc_objsize0 (__s1) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n)) +- return __wmemmove_chk (__s1, __s2, __n, +- __glibc_objsize0 (__s1) / sizeof (wchar_t)); +- +- if (__n > __glibc_objsize0 (__s1) / sizeof (wchar_t)) +- return __wmemmove_chk_warn (__s1, __s2, __n, +- (__glibc_objsize0 (__s1) +- / sizeof (wchar_t))); +- } +- return __wmemmove_alias (__s1, __s2, __n); ++ return __glibc_fortify_n (wmemmove, __n, sizeof (wchar_t), ++ __glibc_objsize0 (__s1), ++ __s1, __s2, __n); + } + + +@@ -101,18 +84,9 @@ __fortify_function wchar_t * + __NTH (wmempcpy (wchar_t *__restrict __s1, const wchar_t *__restrict __s2, + size_t __n)) + { +- if (__glibc_objsize0 (__s1) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n)) +- return __wmempcpy_chk (__s1, __s2, __n, +- __glibc_objsize0 (__s1) / sizeof (wchar_t)); +- +- if (__n > __glibc_objsize0 (__s1) / sizeof (wchar_t)) +- return __wmempcpy_chk_warn (__s1, __s2, __n, +- (__glibc_objsize0 (__s1) +- / sizeof (wchar_t))); +- } +- return __wmempcpy_alias (__s1, __s2, __n); ++ return __glibc_fortify_n (wmempcpy, __n, sizeof (wchar_t), ++ __glibc_objsize0 (__s1), ++ __s1, __s2, __n); + } + #endif + +@@ -130,17 +104,9 @@ extern wchar_t *__REDIRECT_NTH (__wmemset_chk_warn, + __fortify_function wchar_t * + __NTH (wmemset (wchar_t *__s, wchar_t __c, size_t __n)) + { +- if (__glibc_objsize0 (__s) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n)) +- return __wmemset_chk (__s, __c, __n, +- __glibc_objsize0 (__s) / sizeof (wchar_t)); +- +- if (__n > __glibc_objsize0 (__s) / sizeof (wchar_t)) +- return __wmemset_chk_warn (__s, __c, __n, +- __glibc_objsize0 (__s) / sizeof (wchar_t)); +- } +- return __wmemset_alias (__s, __c, __n); ++ return __glibc_fortify_n (wmemset, __n, sizeof (wchar_t), ++ __glibc_objsize0 (__s), ++ __s, __c, __n); + } + + +@@ -154,9 +120,9 @@ extern wchar_t *__REDIRECT_NTH (__wcscpy_alias, + __fortify_function wchar_t * + __NTH (wcscpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src)) + { +- if (__glibc_objsize (__dest) != (size_t) -1) +- return __wcscpy_chk (__dest, __src, +- __glibc_objsize (__dest) / sizeof (wchar_t)); ++ size_t sz = __glibc_objsize (__dest); ++ if (sz != (size_t) -1) ++ return __wcscpy_chk (__dest, __src, sz / sizeof (wchar_t)); + return __wcscpy_alias (__dest, __src); + } + +@@ -171,9 +137,9 @@ extern wchar_t *__REDIRECT_NTH (__wcpcpy_alias, + __fortify_function wchar_t * + __NTH (wcpcpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src)) + { +- if (__glibc_objsize (__dest) != (size_t) -1) +- return __wcpcpy_chk (__dest, __src, +- __glibc_objsize (__dest) / sizeof (wchar_t)); ++ size_t sz = __glibc_objsize (__dest); ++ if (sz != (size_t) -1) ++ return __wcpcpy_chk (__dest, __src, sz / sizeof (wchar_t)); + return __wcpcpy_alias (__dest, __src); + } + +@@ -196,17 +162,9 @@ __fortify_function wchar_t * + __NTH (wcsncpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src, + size_t __n)) + { +- if (__glibc_objsize (__dest) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n)) +- return __wcsncpy_chk (__dest, __src, __n, +- __glibc_objsize (__dest) / sizeof (wchar_t)); +- if (__n > __glibc_objsize (__dest) / sizeof (wchar_t)) +- return __wcsncpy_chk_warn (__dest, __src, __n, +- (__glibc_objsize (__dest) +- / sizeof (wchar_t))); +- } +- return __wcsncpy_alias (__dest, __src, __n); ++ return __glibc_fortify_n (wcsncpy, __n, sizeof (wchar_t), ++ __glibc_objsize (__dest), ++ __dest, __src, __n); + } + + +@@ -228,17 +186,9 @@ __fortify_function wchar_t * + __NTH (wcpncpy (wchar_t *__restrict __dest, const wchar_t *__restrict __src, + size_t __n)) + { +- if (__glibc_objsize (__dest) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n)) +- return __wcpncpy_chk (__dest, __src, __n, +- __glibc_objsize (__dest) / sizeof (wchar_t)); +- if (__n > __glibc_objsize (__dest) / sizeof (wchar_t)) +- return __wcpncpy_chk_warn (__dest, __src, __n, +- (__glibc_objsize (__dest) +- / sizeof (wchar_t))); +- } +- return __wcpncpy_alias (__dest, __src, __n); ++ return __glibc_fortify_n (wcpncpy, __n, sizeof (wchar_t), ++ __glibc_objsize (__dest), ++ __dest, __src, __n); + } + + +@@ -252,9 +202,9 @@ extern wchar_t *__REDIRECT_NTH (__wcscat_alias, + __fortify_function wchar_t * + __NTH (wcscat (wchar_t *__restrict __dest, const wchar_t *__restrict __src)) + { +- if (__glibc_objsize (__dest) != (size_t) -1) +- return __wcscat_chk (__dest, __src, +- __glibc_objsize (__dest) / sizeof (wchar_t)); ++ size_t sz = __glibc_objsize (__dest); ++ if (sz != (size_t) -1) ++ return __wcscat_chk (__dest, __src, sz / sizeof (wchar_t)); + return __wcscat_alias (__dest, __src); + } + +@@ -271,9 +221,9 @@ __fortify_function wchar_t * + __NTH (wcsncat (wchar_t *__restrict __dest, const wchar_t *__restrict __src, + size_t __n)) + { +- if (__glibc_objsize (__dest) != (size_t) -1) +- return __wcsncat_chk (__dest, __src, __n, +- __glibc_objsize (__dest) / sizeof (wchar_t)); ++ size_t sz = __glibc_objsize (__dest); ++ if (sz != (size_t) -1) ++ return __wcsncat_chk (__dest, __src, __n, sz / sizeof (wchar_t)); + return __wcsncat_alias (__dest, __src, __n); + } + +@@ -293,10 +243,10 @@ __fortify_function int + __NTH (swprintf (wchar_t *__restrict __s, size_t __n, + const wchar_t *__restrict __fmt, ...)) + { +- if (__glibc_objsize (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1) ++ size_t sz = __glibc_objsize (__s); ++ if (sz != (size_t) -1 || __USE_FORTIFY_LEVEL > 1) + return __swprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, +- __glibc_objsize (__s) / sizeof (wchar_t), +- __fmt, __va_arg_pack ()); ++ sz / sizeof (wchar_t), __fmt, __va_arg_pack ()); + return __swprintf_alias (__s, __n, __fmt, __va_arg_pack ()); + } + #elif !defined __cplusplus +@@ -323,10 +273,10 @@ __fortify_function int + __NTH (vswprintf (wchar_t *__restrict __s, size_t __n, + const wchar_t *__restrict __fmt, __gnuc_va_list __ap)) + { +- if (__glibc_objsize (__s) != (size_t) -1 || __USE_FORTIFY_LEVEL > 1) ++ size_t sz = __glibc_objsize (__s); ++ if (sz != (size_t) -1 || __USE_FORTIFY_LEVEL > 1) + return __vswprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1, +- __glibc_objsize (__s) / sizeof (wchar_t), __fmt, +- __ap); ++ sz / sizeof (wchar_t), __fmt, __ap); + return __vswprintf_alias (__s, __n, __fmt, __ap); + } + +@@ -392,18 +342,12 @@ extern wchar_t *__REDIRECT (__fgetws_chk_warn, + __fortify_function __wur wchar_t * + fgetws (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream) + { +- if (__glibc_objsize (__s) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n) || __n <= 0) +- return __fgetws_chk (__s, __glibc_objsize (__s) / sizeof (wchar_t), +- __n, __stream); +- +- if ((size_t) __n > __glibc_objsize (__s) / sizeof (wchar_t)) +- return __fgetws_chk_warn (__s, +- __glibc_objsize (__s) / sizeof (wchar_t), +- __n, __stream); +- } +- return __fgetws_alias (__s, __n, __stream); ++ size_t sz = __glibc_objsize (__s); ++ if (__glibc_safe_or_unknown_len (__n, sizeof (wchar_t), sz)) ++ return __fgetws_alias (__s, __n, __stream); ++ if (__glibc_unsafe_len (__n, sizeof (wchar_t), sz)) ++ return __fgetws_chk_warn (__s, sz / sizeof (wchar_t), __n, __stream); ++ return __fgetws_chk (__s, sz / sizeof (wchar_t), __n, __stream); + } + + #ifdef __USE_GNU +@@ -424,20 +368,13 @@ extern wchar_t *__REDIRECT (__fgetws_unlocked_chk_warn, + __fortify_function __wur wchar_t * + fgetws_unlocked (wchar_t *__restrict __s, int __n, __FILE *__restrict __stream) + { +- if (__glibc_objsize (__s) != (size_t) -1) +- { +- if (!__builtin_constant_p (__n) || __n <= 0) +- return __fgetws_unlocked_chk (__s, +- __glibc_objsize (__s) / sizeof (wchar_t), +- __n, __stream); +- +- if ((size_t) __n > __glibc_objsize (__s) / sizeof (wchar_t)) +- return __fgetws_unlocked_chk_warn (__s, +- (__glibc_objsize (__s) +- / sizeof (wchar_t)), +- __n, __stream); +- } +- return __fgetws_unlocked_alias (__s, __n, __stream); ++ size_t sz = __glibc_objsize (__s); ++ if (__glibc_safe_or_unknown_len (__n, sizeof (wchar_t), sz)) ++ return __fgetws_unlocked_alias (__s, __n, __stream); ++ if (__glibc_unsafe_len (__n, sizeof (wchar_t), sz)) ++ return __fgetws_unlocked_chk_warn (__s, sz / sizeof (wchar_t), __n, ++ __stream); ++ return __fgetws_unlocked_chk (__s, sz / sizeof (wchar_t), __n, __stream); + } + #endif + +@@ -488,18 +425,9 @@ __fortify_function size_t + __NTH (mbsrtowcs (wchar_t *__restrict __dst, const char **__restrict __src, + size_t __len, mbstate_t *__restrict __ps)) + { +- if (__glibc_objsize (__dst) != (size_t) -1) +- { +- if (!__builtin_constant_p (__len)) +- return __mbsrtowcs_chk (__dst, __src, __len, __ps, +- __glibc_objsize (__dst) / sizeof (wchar_t)); +- +- if (__len > __glibc_objsize (__dst) / sizeof (wchar_t)) +- return __mbsrtowcs_chk_warn (__dst, __src, __len, __ps, +- (__glibc_objsize (__dst) +- / sizeof (wchar_t))); +- } +- return __mbsrtowcs_alias (__dst, __src, __len, __ps); ++ return __glibc_fortify_n (mbsrtowcs, __len, sizeof (wchar_t), ++ __glibc_objsize (__dst), ++ __dst, __src, __len, __ps); + } + + +@@ -523,17 +451,9 @@ __fortify_function size_t + __NTH (wcsrtombs (char *__restrict __dst, const wchar_t **__restrict __src, + size_t __len, mbstate_t *__restrict __ps)) + { +- if (__glibc_objsize (__dst) != (size_t) -1) +- { +- if (!__builtin_constant_p (__len)) +- return __wcsrtombs_chk (__dst, __src, __len, __ps, +- __glibc_objsize (__dst)); +- +- if (__len > __glibc_objsize (__dst)) +- return __wcsrtombs_chk_warn (__dst, __src, __len, __ps, +- __glibc_objsize (__dst)); +- } +- return __wcsrtombs_alias (__dst, __src, __len, __ps); ++ return __glibc_fortify (wcsrtombs, __len, sizeof (char), ++ __glibc_objsize (__dst), ++ __dst, __src, __len, __ps); + } + + +@@ -559,18 +479,9 @@ __fortify_function size_t + __NTH (mbsnrtowcs (wchar_t *__restrict __dst, const char **__restrict __src, + size_t __nmc, size_t __len, mbstate_t *__restrict __ps)) + { +- if (__glibc_objsize (__dst) != (size_t) -1) +- { +- if (!__builtin_constant_p (__len)) +- return __mbsnrtowcs_chk (__dst, __src, __nmc, __len, __ps, +- __glibc_objsize (__dst) / sizeof (wchar_t)); +- +- if (__len > __glibc_objsize (__dst) / sizeof (wchar_t)) +- return __mbsnrtowcs_chk_warn (__dst, __src, __nmc, __len, __ps, +- (__glibc_objsize (__dst) +- / sizeof (wchar_t))); +- } +- return __mbsnrtowcs_alias (__dst, __src, __nmc, __len, __ps); ++ return __glibc_fortify_n (mbsnrtowcs, __len, sizeof (wchar_t), ++ __glibc_objsize (__dst), ++ __dst, __src, __nmc, __len, __ps); + } + + +@@ -596,16 +507,8 @@ __fortify_function size_t + __NTH (wcsnrtombs (char *__restrict __dst, const wchar_t **__restrict __src, + size_t __nwc, size_t __len, mbstate_t *__restrict __ps)) + { +- if (__glibc_objsize (__dst) != (size_t) -1) +- { +- if (!__builtin_constant_p (__len)) +- return __wcsnrtombs_chk (__dst, __src, __nwc, __len, __ps, +- __glibc_objsize (__dst)); +- +- if (__len > __glibc_objsize (__dst)) +- return __wcsnrtombs_chk_warn (__dst, __src, __nwc, __len, __ps, +- __glibc_objsize (__dst)); +- } +- return __wcsnrtombs_alias (__dst, __src, __nwc, __len, __ps); ++ return __glibc_fortify (wcsnrtombs, __len, sizeof (char), ++ __glibc_objsize (__dst), ++ __dst, __src, __nwc, __len, __ps); + } + #endif diff --git a/SOURCES/glibc-rh2033684-7.patch b/SOURCES/glibc-rh2033684-7.patch new file mode 100644 index 0000000..7cb18a6 --- /dev/null +++ b/SOURCES/glibc-rh2033684-7.patch @@ -0,0 +1,43 @@ +commit fadf75c370494da6a02274ebe79e45b2f22ebbd0 +Author: Florian Weimer +Date: Mon Feb 10 14:37:10 2020 +0100 + + debug: Add missing locale dependencies of fortify tests + + The missing dependencies result in failures like this if make check + is invoked with sufficient parallelism for the debug subdirectory: + + FAIL: debug/tst-chk2 + FAIL: debug/tst-chk3 + FAIL: debug/tst-chk4 + FAIL: debug/tst-chk5 + FAIL: debug/tst-chk6 + FAIL: debug/tst-lfschk1 + FAIL: debug/tst-lfschk2 + FAIL: debug/tst-lfschk3 + FAIL: debug/tst-lfschk4 + FAIL: debug/tst-lfschk5 + FAIL: debug/tst-lfschk6 + +diff --git a/debug/Makefile b/debug/Makefile +index 506cebc3c4ca19ff..5e45c9b41077f2fd 100644 +--- a/debug/Makefile ++++ b/debug/Makefile +@@ -188,6 +188,17 @@ LOCALES := de_DE.UTF-8 + include ../gen-locales.mk + + $(objpfx)tst-chk1.out: $(gen-locales) ++$(objpfx)tst-chk2.out: $(gen-locales) ++$(objpfx)tst-chk3.out: $(gen-locales) ++$(objpfx)tst-chk4.out: $(gen-locales) ++$(objpfx)tst-chk5.out: $(gen-locales) ++$(objpfx)tst-chk6.out: $(gen-locales) ++$(objpfx)tst-lfschk1.out: $(gen-locales) ++$(objpfx)tst-lfschk2.out: $(gen-locales) ++$(objpfx)tst-lfschk3.out: $(gen-locales) ++$(objpfx)tst-lfschk4.out: $(gen-locales) ++$(objpfx)tst-lfschk5.out: $(gen-locales) ++$(objpfx)tst-lfschk6.out: $(gen-locales) + endif + + sLIBdir := $(shell echo $(slibdir) | sed 's,lib\(\|64\)$$,\\\\$$LIB,') diff --git a/SOURCES/glibc-rh2033684-8.patch b/SOURCES/glibc-rh2033684-8.patch new file mode 100644 index 0000000..5b90b20 --- /dev/null +++ b/SOURCES/glibc-rh2033684-8.patch @@ -0,0 +1,357 @@ +commit ad6f2a010c2ce759936de4747f6e0d53991912f8 +Author: Siddhesh Poyarekar +Date: Wed Oct 20 18:13:05 2021 +0530 + + debug: Add tests for _FORTIFY_SOURCE=3 + + Add some testing coverage for _FORTIFY_SOURCE=3. + + Signed-off-by: Siddhesh Poyarekar + Reviewed-by: Adhemerval Zanella + +diff --git a/debug/Makefile b/debug/Makefile +index 5e45c9b41077f2fd..81361438fc3d2aa9 100644 +--- a/debug/Makefile ++++ b/debug/Makefile +@@ -120,6 +120,8 @@ CFLAGS-tst-chk3.c += -Wno-format -Wno-deprecated-declarations -Wno-error + CFLAGS-tst-chk4.cc += -Wno-format -Wno-deprecated-declarations -Wno-error + CFLAGS-tst-chk5.cc += -Wno-format -Wno-deprecated-declarations -Wno-error + CFLAGS-tst-chk6.cc += -Wno-format -Wno-deprecated-declarations -Wno-error ++CFLAGS-tst-chk7.c += -Wno-format -Wno-deprecated-declarations -Wno-error ++CFLAGS-tst-chk8.cc += -Wno-format -Wno-deprecated-declarations -Wno-error + CFLAGS-tst-lfschk1.c += -Wno-format -Wno-deprecated-declarations -Wno-error + CFLAGS-tst-lfschk2.c += -Wno-format -Wno-deprecated-declarations -Wno-error + CFLAGS-tst-lfschk3.c += -Wno-format -Wno-deprecated-declarations -Wno-error +@@ -129,6 +131,7 @@ CFLAGS-tst-lfschk6.cc += -Wno-format -Wno-deprecated-declarations -Wno-error + LDLIBS-tst-chk4 = -lstdc++ + LDLIBS-tst-chk5 = -lstdc++ + LDLIBS-tst-chk6 = -lstdc++ ++LDLIBS-tst-chk8 = -lstdc++ + LDLIBS-tst-lfschk4 = -lstdc++ + LDLIBS-tst-lfschk5 = -lstdc++ + LDLIBS-tst-lfschk6 = -lstdc++ +@@ -150,16 +153,16 @@ CFLAGS-tst-ssp-1.c += -fstack-protector-all + + tests = backtrace-tst tst-longjmp_chk tst-chk1 tst-chk2 tst-chk3 \ + tst-lfschk1 tst-lfschk2 tst-lfschk3 test-strcpy_chk test-stpcpy_chk \ +- tst-chk4 tst-chk5 tst-chk6 tst-lfschk4 tst-lfschk5 tst-lfschk6 \ +- tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 tst-backtrace4 \ +- tst-backtrace5 tst-backtrace6 ++ tst-chk4 tst-chk5 tst-chk6 tst-chk7 tst-chk8 tst-lfschk4 tst-lfschk5 \ ++ tst-lfschk6 tst-longjmp_chk2 tst-backtrace2 tst-backtrace3 \ ++ tst-backtrace4 tst-backtrace5 tst-backtrace6 + + ifeq ($(have-ssp),yes) + tests += tst-ssp-1 + endif + + ifeq (,$(CXX)) +-tests-unsupported = tst-chk4 tst-chk5 tst-chk6 \ ++tests-unsupported = tst-chk4 tst-chk5 tst-chk6 tst-chk8 \ + tst-lfschk4 tst-lfschk5 tst-lfschk6 + endif + +@@ -193,6 +196,8 @@ $(objpfx)tst-chk3.out: $(gen-locales) + $(objpfx)tst-chk4.out: $(gen-locales) + $(objpfx)tst-chk5.out: $(gen-locales) + $(objpfx)tst-chk6.out: $(gen-locales) ++$(objpfx)tst-chk7.out: $(gen-locales) ++$(objpfx)tst-chk8.out: $(gen-locales) + $(objpfx)tst-lfschk1.out: $(gen-locales) + $(objpfx)tst-lfschk2.out: $(gen-locales) + $(objpfx)tst-lfschk3.out: $(gen-locales) +diff --git a/debug/tst-chk1.c b/debug/tst-chk1.c +index ca2b524b2fa6404c..5e76081255316a93 100644 +--- a/debug/tst-chk1.c ++++ b/debug/tst-chk1.c +@@ -83,8 +83,14 @@ handler (int sig) + _exit (127); + } + ++#if __USE_FORTIFY_LEVEL == 3 ++volatile size_t buf_size = 10; ++#else + char buf[10]; + wchar_t wbuf[10]; ++#define buf_size sizeof (buf) ++#endif ++ + volatile size_t l0; + volatile char *p; + volatile wchar_t *wp; +@@ -123,6 +129,10 @@ int num2 = 987654; + static int + do_test (void) + { ++#if __USE_FORTIFY_LEVEL == 3 ++ char *buf = (char *) malloc (buf_size); ++ wchar_t *wbuf = (wchar_t *) malloc (buf_size * sizeof (wchar_t)); ++#endif + set_fortify_handler (handler); + + struct A { char buf1[9]; char buf2[1]; } a; +@@ -947,93 +957,93 @@ do_test (void) + + rewind (stdin); + +- if (fgets (buf, sizeof (buf), stdin) != buf ++ if (fgets (buf, buf_size, stdin) != buf + || memcmp (buf, "abcdefgh\n", 10)) + FAIL (); +- if (fgets (buf, sizeof (buf), stdin) != buf || memcmp (buf, "ABCDEFGHI", 10)) ++ if (fgets (buf, buf_size, stdin) != buf || memcmp (buf, "ABCDEFGHI", 10)) + FAIL (); + + rewind (stdin); + +- if (fgets (buf, l0 + sizeof (buf), stdin) != buf ++ if (fgets (buf, l0 + buf_size, stdin) != buf + || memcmp (buf, "abcdefgh\n", 10)) + FAIL (); + + #if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START +- if (fgets (buf, sizeof (buf) + 1, stdin) != buf) ++ if (fgets (buf, buf_size + 1, stdin) != buf) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START +- if (fgets (buf, l0 + sizeof (buf) + 1, stdin) != buf) ++ if (fgets (buf, l0 + buf_size + 1, stdin) != buf) + FAIL (); + CHK_FAIL_END + #endif + + rewind (stdin); + +- if (fgets_unlocked (buf, sizeof (buf), stdin) != buf ++ if (fgets_unlocked (buf, buf_size, stdin) != buf + || memcmp (buf, "abcdefgh\n", 10)) + FAIL (); +- if (fgets_unlocked (buf, sizeof (buf), stdin) != buf ++ if (fgets_unlocked (buf, buf_size, stdin) != buf + || memcmp (buf, "ABCDEFGHI", 10)) + FAIL (); + + rewind (stdin); + +- if (fgets_unlocked (buf, l0 + sizeof (buf), stdin) != buf ++ if (fgets_unlocked (buf, l0 + buf_size, stdin) != buf + || memcmp (buf, "abcdefgh\n", 10)) + FAIL (); + + #if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START +- if (fgets_unlocked (buf, sizeof (buf) + 1, stdin) != buf) ++ if (fgets_unlocked (buf, buf_size + 1, stdin) != buf) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START +- if (fgets_unlocked (buf, l0 + sizeof (buf) + 1, stdin) != buf) ++ if (fgets_unlocked (buf, l0 + buf_size + 1, stdin) != buf) + FAIL (); + CHK_FAIL_END + #endif + + rewind (stdin); + +- if (fread (buf, 1, sizeof (buf), stdin) != sizeof (buf) ++ if (fread (buf, 1, buf_size, stdin) != buf_size + || memcmp (buf, "abcdefgh\nA", 10)) + FAIL (); +- if (fread (buf, sizeof (buf), 1, stdin) != 1 ++ if (fread (buf, buf_size, 1, stdin) != 1 + || memcmp (buf, "BCDEFGHI\na", 10)) + FAIL (); + + rewind (stdin); + +- if (fread (buf, l0 + 1, sizeof (buf), stdin) != sizeof (buf) ++ if (fread (buf, l0 + 1, buf_size, stdin) != buf_size + || memcmp (buf, "abcdefgh\nA", 10)) + FAIL (); +- if (fread (buf, sizeof (buf), l0 + 1, stdin) != 1 ++ if (fread (buf, buf_size, l0 + 1, stdin) != 1 + || memcmp (buf, "BCDEFGHI\na", 10)) + FAIL (); + + #if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START +- if (fread (buf, 1, sizeof (buf) + 1, stdin) != sizeof (buf) + 1) ++ if (fread (buf, 1, buf_size + 1, stdin) != buf_size + 1) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START +- if (fread (buf, sizeof (buf) + 1, l0 + 1, stdin) != 1) ++ if (fread (buf, buf_size + 1, l0 + 1, stdin) != 1) + FAIL (); + CHK_FAIL_END + #endif + + rewind (stdin); + +- if (fread_unlocked (buf, 1, sizeof (buf), stdin) != sizeof (buf) ++ if (fread_unlocked (buf, 1, buf_size, stdin) != buf_size + || memcmp (buf, "abcdefgh\nA", 10)) + FAIL (); +- if (fread_unlocked (buf, sizeof (buf), 1, stdin) != 1 ++ if (fread_unlocked (buf, buf_size, 1, stdin) != 1 + || memcmp (buf, "BCDEFGHI\na", 10)) + FAIL (); + +@@ -1048,100 +1058,100 @@ do_test (void) + + rewind (stdin); + +- if (fread_unlocked (buf, l0 + 1, sizeof (buf), stdin) != sizeof (buf) ++ if (fread_unlocked (buf, l0 + 1, buf_size, stdin) != buf_size + || memcmp (buf, "abcdefgh\nA", 10)) + FAIL (); +- if (fread_unlocked (buf, sizeof (buf), l0 + 1, stdin) != 1 ++ if (fread_unlocked (buf, buf_size, l0 + 1, stdin) != 1 + || memcmp (buf, "BCDEFGHI\na", 10)) + FAIL (); + + #if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START +- if (fread_unlocked (buf, 1, sizeof (buf) + 1, stdin) != sizeof (buf) + 1) ++ if (fread_unlocked (buf, 1, buf_size + 1, stdin) != buf_size + 1) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START +- if (fread_unlocked (buf, sizeof (buf) + 1, l0 + 1, stdin) != 1) ++ if (fread_unlocked (buf, buf_size + 1, l0 + 1, stdin) != 1) + FAIL (); + CHK_FAIL_END + #endif + + lseek (fileno (stdin), 0, SEEK_SET); + +- if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1 ++ if (read (fileno (stdin), buf, buf_size - 1) != buf_size - 1 + || memcmp (buf, "abcdefgh\n", 9)) + FAIL (); +- if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1 ++ if (read (fileno (stdin), buf, buf_size - 1) != buf_size - 1 + || memcmp (buf, "ABCDEFGHI", 9)) + FAIL (); + + lseek (fileno (stdin), 0, SEEK_SET); + +- if (read (fileno (stdin), buf, l0 + sizeof (buf) - 1) != sizeof (buf) - 1 ++ if (read (fileno (stdin), buf, l0 + buf_size - 1) != buf_size - 1 + || memcmp (buf, "abcdefgh\n", 9)) + FAIL (); + + #if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START +- if (read (fileno (stdin), buf, sizeof (buf) + 1) != sizeof (buf) + 1) ++ if (read (fileno (stdin), buf, buf_size + 1) != buf_size + 1) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START +- if (read (fileno (stdin), buf, l0 + sizeof (buf) + 1) != sizeof (buf) + 1) ++ if (read (fileno (stdin), buf, l0 + buf_size + 1) != buf_size + 1) + FAIL (); + CHK_FAIL_END + #endif + +- if (pread (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2) +- != sizeof (buf) - 1 ++ if (pread (fileno (stdin), buf, buf_size - 1, buf_size - 2) ++ != buf_size - 1 + || memcmp (buf, "\nABCDEFGH", 9)) + FAIL (); +- if (pread (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1 ++ if (pread (fileno (stdin), buf, buf_size - 1, 0) != buf_size - 1 + || memcmp (buf, "abcdefgh\n", 9)) + FAIL (); +- if (pread (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3) +- != sizeof (buf) - 1 ++ if (pread (fileno (stdin), buf, l0 + buf_size - 1, buf_size - 3) ++ != buf_size - 1 + || memcmp (buf, "h\nABCDEFG", 9)) + FAIL (); + + #if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START +- if (pread (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf)) +- != sizeof (buf) + 1) ++ if (pread (fileno (stdin), buf, buf_size + 1, 2 * buf_size) ++ != buf_size + 1) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START +- if (pread (fileno (stdin), buf, l0 + sizeof (buf) + 1, 2 * sizeof (buf)) +- != sizeof (buf) + 1) ++ if (pread (fileno (stdin), buf, l0 + buf_size + 1, 2 * buf_size) ++ != buf_size + 1) + FAIL (); + CHK_FAIL_END + #endif + +- if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2) +- != sizeof (buf) - 1 ++ if (pread64 (fileno (stdin), buf, buf_size - 1, buf_size - 2) ++ != buf_size - 1 + || memcmp (buf, "\nABCDEFGH", 9)) + FAIL (); +- if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1 ++ if (pread64 (fileno (stdin), buf, buf_size - 1, 0) != buf_size - 1 + || memcmp (buf, "abcdefgh\n", 9)) + FAIL (); +- if (pread64 (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3) +- != sizeof (buf) - 1 ++ if (pread64 (fileno (stdin), buf, l0 + buf_size - 1, buf_size - 3) ++ != buf_size - 1 + || memcmp (buf, "h\nABCDEFG", 9)) + FAIL (); + + #if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START +- if (pread64 (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf)) +- != sizeof (buf) + 1) ++ if (pread64 (fileno (stdin), buf, buf_size + 1, 2 * buf_size) ++ != buf_size + 1) + FAIL (); + CHK_FAIL_END + + CHK_FAIL_START +- if (pread64 (fileno (stdin), buf, l0 + sizeof (buf) + 1, 2 * sizeof (buf)) +- != sizeof (buf) + 1) ++ if (pread64 (fileno (stdin), buf, l0 + buf_size + 1, 2 * buf_size) ++ != buf_size + 1) + FAIL (); + CHK_FAIL_END + #endif +@@ -1179,7 +1189,7 @@ do_test (void) + CHK_FAIL2_END + + CHK_FAIL2_START +- snprintf (buf, sizeof (buf), "%3$d\n", 1, 2, 3, 4); ++ snprintf (buf, buf_size, "%3$d\n", 1, 2, 3, 4); + CHK_FAIL2_END + + int sp[2]; +diff --git a/debug/tst-chk7.c b/debug/tst-chk7.c +new file mode 100644 +index 0000000000000000..2a7b32381268135c +--- /dev/null ++++ b/debug/tst-chk7.c +@@ -0,0 +1,2 @@ ++#define _FORTIFY_SOURCE 3 ++#include "tst-chk1.c" +diff --git a/debug/tst-chk8.cc b/debug/tst-chk8.cc +new file mode 100644 +index 0000000000000000..2a7b32381268135c +--- /dev/null ++++ b/debug/tst-chk8.cc +@@ -0,0 +1,2 @@ ++#define _FORTIFY_SOURCE 3 ++#include "tst-chk1.c" diff --git a/SOURCES/glibc-rh2033684-9.patch b/SOURCES/glibc-rh2033684-9.patch new file mode 100644 index 0000000..467ece4 --- /dev/null +++ b/SOURCES/glibc-rh2033684-9.patch @@ -0,0 +1,23 @@ +commit ae23fa3e5fe24daf94fc7f8e5268bb8ceeda7477 +Author: Siddhesh Poyarekar +Date: Thu Dec 16 07:19:14 2021 +0530 + + __glibc_unsafe_len: Fix comment + + We know that the length is *unsafe*. + + Signed-off-by: Siddhesh Poyarekar + +diff --git a/misc/sys/cdefs.h b/misc/sys/cdefs.h +index 17b84a2e6c69d961..147339957c4ad490 100644 +--- a/misc/sys/cdefs.h ++++ b/misc/sys/cdefs.h +@@ -150,7 +150,7 @@ + __s, __osz)) \ + && __glibc_safe_len_cond ((__SIZE_TYPE__) (__l), __s, __osz)) + +-/* Conversely, we know at compile time that the length is safe if the ++/* Conversely, we know at compile time that the length is unsafe if the + __L * __S <= __OBJSZ condition can be folded to a constant and if it is + false. */ + #define __glibc_unsafe_len(__l, __s, __osz) \ diff --git a/SOURCES/glibc-rh2037416-1.patch b/SOURCES/glibc-rh2037416-1.patch new file mode 100644 index 0000000..3fddefe --- /dev/null +++ b/SOURCES/glibc-rh2037416-1.patch @@ -0,0 +1,136 @@ +From 07b427296b8d59f439144029d9a948f6c1ce0a31 Mon Sep 17 00:00:00 2001 +From: Wilco Dijkstra +Date: Tue, 10 Aug 2021 13:30:27 +0100 +Subject: [PATCH] [1/5] AArch64: Improve A64FX memset for small sizes + +Improve performance of small memsets by reducing instruction counts and +improving code alignment. Bench-memset shows 35-45% performance gain for +small sizes. + +Reviewed-by: Naohiro Tamura +--- + sysdeps/aarch64/multiarch/memset_a64fx.S | 96 +++++++++--------------- + 1 file changed, 36 insertions(+), 60 deletions(-) + +diff --git a/sysdeps/aarch64/multiarch/memset_a64fx.S b/sysdeps/aarch64/multiarch/memset_a64fx.S +index ce54e5418b..cf3d402ef6 100644 +--- a/sysdeps/aarch64/multiarch/memset_a64fx.S ++++ b/sysdeps/aarch64/multiarch/memset_a64fx.S +@@ -51,78 +51,54 @@ + .endm + + .macro st1b_unroll first=0, last=7 +- st1b z0.b, p0, [dst, #\first, mul vl] ++ st1b z0.b, p0, [dst, \first, mul vl] + .if \last-\first + st1b_unroll "(\first+1)", \last + .endif + .endm + +- .macro shortcut_for_small_size exit +- // if rest <= vector_length * 2 +- whilelo p0.b, xzr, count +- whilelo p1.b, vector_length, count +- b.last 1f +- st1b z0.b, p0, [dstin, #0, mul vl] +- st1b z0.b, p1, [dstin, #1, mul vl] +- ret +-1: // if rest > vector_length * 8 +- cmp count, vector_length, lsl 3 // vector_length * 8 +- b.hi \exit +- // if rest <= vector_length * 4 +- lsl tmp1, vector_length, 1 // vector_length * 2 +- whilelo p2.b, tmp1, count +- incb tmp1 +- whilelo p3.b, tmp1, count +- b.last 1f +- st1b z0.b, p0, [dstin, #0, mul vl] +- st1b z0.b, p1, [dstin, #1, mul vl] +- st1b z0.b, p2, [dstin, #2, mul vl] +- st1b z0.b, p3, [dstin, #3, mul vl] +- ret +-1: // if rest <= vector_length * 8 +- lsl tmp1, vector_length, 2 // vector_length * 4 +- whilelo p4.b, tmp1, count +- incb tmp1 +- whilelo p5.b, tmp1, count +- b.last 1f +- st1b z0.b, p0, [dstin, #0, mul vl] +- st1b z0.b, p1, [dstin, #1, mul vl] +- st1b z0.b, p2, [dstin, #2, mul vl] +- st1b z0.b, p3, [dstin, #3, mul vl] +- st1b z0.b, p4, [dstin, #4, mul vl] +- st1b z0.b, p5, [dstin, #5, mul vl] +- ret +-1: lsl tmp1, vector_length, 2 // vector_length * 4 +- incb tmp1 // vector_length * 5 +- incb tmp1 // vector_length * 6 +- whilelo p6.b, tmp1, count +- incb tmp1 +- whilelo p7.b, tmp1, count +- st1b z0.b, p0, [dstin, #0, mul vl] +- st1b z0.b, p1, [dstin, #1, mul vl] +- st1b z0.b, p2, [dstin, #2, mul vl] +- st1b z0.b, p3, [dstin, #3, mul vl] +- st1b z0.b, p4, [dstin, #4, mul vl] +- st1b z0.b, p5, [dstin, #5, mul vl] +- st1b z0.b, p6, [dstin, #6, mul vl] +- st1b z0.b, p7, [dstin, #7, mul vl] +- ret +- .endm + +-ENTRY (MEMSET) ++#undef BTI_C ++#define BTI_C + ++ENTRY (MEMSET) + PTR_ARG (0) + SIZE_ARG (2) + +- cbnz count, 1f +- ret +-1: dup z0.b, valw + cntb vector_length +- // shortcut for less than vector_length * 8 +- // gives a free ptrue to p0.b for n >= vector_length +- shortcut_for_small_size L(vl_agnostic) +- // end of shortcut ++ dup z0.b, valw ++ whilelo p0.b, vector_length, count ++ b.last 1f ++ whilelo p1.b, xzr, count ++ st1b z0.b, p1, [dstin, 0, mul vl] ++ st1b z0.b, p0, [dstin, 1, mul vl] ++ ret ++ ++ // count >= vector_length * 2 ++1: cmp count, vector_length, lsl 2 ++ add dstend, dstin, count ++ b.hi 1f ++ st1b z0.b, p0, [dstin, 0, mul vl] ++ st1b z0.b, p0, [dstin, 1, mul vl] ++ st1b z0.b, p0, [dstend, -2, mul vl] ++ st1b z0.b, p0, [dstend, -1, mul vl] ++ ret ++ ++ // count > vector_length * 4 ++1: lsl tmp1, vector_length, 3 ++ cmp count, tmp1 ++ b.hi L(vl_agnostic) ++ st1b z0.b, p0, [dstin, 0, mul vl] ++ st1b z0.b, p0, [dstin, 1, mul vl] ++ st1b z0.b, p0, [dstin, 2, mul vl] ++ st1b z0.b, p0, [dstin, 3, mul vl] ++ st1b z0.b, p0, [dstend, -4, mul vl] ++ st1b z0.b, p0, [dstend, -3, mul vl] ++ st1b z0.b, p0, [dstend, -2, mul vl] ++ st1b z0.b, p0, [dstend, -1, mul vl] ++ ret + ++ .p2align 4 + L(vl_agnostic): // VL Agnostic + mov rest, count + mov dst, dstin +-- +2.31.1 + diff --git a/SOURCES/glibc-rh2037416-2.patch b/SOURCES/glibc-rh2037416-2.patch new file mode 100644 index 0000000..e991e91 --- /dev/null +++ b/SOURCES/glibc-rh2037416-2.patch @@ -0,0 +1,131 @@ +From 9bc2ed8f46d80859a5596789cc9e8cc2de84b0e7 Mon Sep 17 00:00:00 2001 +From: Wilco Dijkstra +Date: Tue, 10 Aug 2021 13:39:37 +0100 +Subject: [PATCH] [2/5] AArch64: Improve A64FX memset for large sizes + +Improve performance of large memsets. Simplify alignment code. For zero memset +use DC ZVA, which almost doubles performance. For non-zero memsets use the +unroll8 loop which is about 10% faster. + +Reviewed-by: Naohiro Tamura +--- + sysdeps/aarch64/multiarch/memset_a64fx.S | 85 +++++++----------------- + 1 file changed, 25 insertions(+), 60 deletions(-) + +diff --git a/sysdeps/aarch64/multiarch/memset_a64fx.S b/sysdeps/aarch64/multiarch/memset_a64fx.S +index cf3d402ef6..75cf43ae79 100644 +--- a/sysdeps/aarch64/multiarch/memset_a64fx.S ++++ b/sysdeps/aarch64/multiarch/memset_a64fx.S +@@ -27,14 +27,11 @@ + */ + + #define L1_SIZE (64*1024) // L1 64KB +-#define L2_SIZE (8*1024*1024) // L2 8MB - 1MB ++#define L2_SIZE (8*1024*1024) // L2 8MB + #define CACHE_LINE_SIZE 256 + #define PF_DIST_L1 (CACHE_LINE_SIZE * 16) // Prefetch distance L1 +-#define ZF_DIST (CACHE_LINE_SIZE * 21) // Zerofill distance +-#define rest x8 ++#define rest x2 + #define vector_length x9 +-#define vl_remainder x10 // vector_length remainder +-#define cl_remainder x11 // CACHE_LINE_SIZE remainder + + #if HAVE_AARCH64_SVE_ASM + # if IS_IN (libc) +@@ -42,14 +39,6 @@ + + .arch armv8.2-a+sve + +- .macro dc_zva times +- dc zva, tmp1 +- add tmp1, tmp1, CACHE_LINE_SIZE +- .if \times-1 +- dc_zva "(\times-1)" +- .endif +- .endm +- + .macro st1b_unroll first=0, last=7 + st1b z0.b, p0, [dst, \first, mul vl] + .if \last-\first +@@ -188,54 +177,30 @@ L(L1_prefetch): // if rest >= L1_SIZE + cbnz rest, L(unroll32) + ret + +-L(L2): +- // align dst address at vector_length byte boundary +- sub tmp1, vector_length, 1 +- ands tmp2, dst, tmp1 +- // if vl_remainder == 0 +- b.eq 1f +- sub vl_remainder, vector_length, tmp2 +- // process remainder until the first vector_length boundary +- whilelt p2.b, xzr, vl_remainder +- st1b z0.b, p2, [dst] +- add dst, dst, vl_remainder +- sub rest, rest, vl_remainder +- // align dstin address at CACHE_LINE_SIZE byte boundary +-1: mov tmp1, CACHE_LINE_SIZE +- ands tmp2, dst, CACHE_LINE_SIZE - 1 +- // if cl_remainder == 0 +- b.eq L(L2_dc_zva) +- sub cl_remainder, tmp1, tmp2 +- // process remainder until the first CACHE_LINE_SIZE boundary +- mov tmp1, xzr // index +-2: whilelt p2.b, tmp1, cl_remainder +- st1b z0.b, p2, [dst, tmp1] +- incb tmp1 +- cmp tmp1, cl_remainder +- b.lo 2b +- add dst, dst, cl_remainder +- sub rest, rest, cl_remainder +- +-L(L2_dc_zva): +- // zero fill +- mov tmp1, dst +- dc_zva (ZF_DIST / CACHE_LINE_SIZE) - 1 +- mov zva_len, ZF_DIST +- add tmp1, zva_len, CACHE_LINE_SIZE * 2 +- // unroll ++ // count >= L2_SIZE + .p2align 3 +-1: st1b_unroll 0, 3 +- add tmp2, dst, zva_len +- dc zva, tmp2 +- st1b_unroll 4, 7 +- add tmp2, tmp2, CACHE_LINE_SIZE +- dc zva, tmp2 +- add dst, dst, CACHE_LINE_SIZE * 2 +- sub rest, rest, CACHE_LINE_SIZE * 2 +- cmp rest, tmp1 // ZF_DIST + CACHE_LINE_SIZE * 2 +- b.ge 1b +- cbnz rest, L(unroll8) +- ret ++L(L2): ++ tst valw, 255 ++ b.ne L(unroll8) ++ // align dst to CACHE_LINE_SIZE byte boundary ++ and tmp2, dst, CACHE_LINE_SIZE - 1 ++ st1b z0.b, p0, [dst, 0, mul vl] ++ st1b z0.b, p0, [dst, 1, mul vl] ++ st1b z0.b, p0, [dst, 2, mul vl] ++ st1b z0.b, p0, [dst, 3, mul vl] ++ sub dst, dst, tmp2 ++ add count, count, tmp2 ++ ++ // clear cachelines using DC ZVA ++ sub count, count, CACHE_LINE_SIZE * 2 ++ .p2align 4 ++1: add dst, dst, CACHE_LINE_SIZE ++ dc zva, dst ++ subs count, count, CACHE_LINE_SIZE ++ b.hi 1b ++ add count, count, CACHE_LINE_SIZE ++ add dst, dst, CACHE_LINE_SIZE ++ b L(last) + + END (MEMSET) + libc_hidden_builtin_def (MEMSET) +-- +2.31.1 + diff --git a/SOURCES/glibc-rh2037416-3.patch b/SOURCES/glibc-rh2037416-3.patch new file mode 100644 index 0000000..3ac7aa2 --- /dev/null +++ b/SOURCES/glibc-rh2037416-3.patch @@ -0,0 +1,80 @@ +From 186092c6ba8825598ffdbf15dbf0823c771f560d Mon Sep 17 00:00:00 2001 +From: Wilco Dijkstra +Date: Tue, 10 Aug 2021 13:42:07 +0100 +Subject: [PATCH] [3/5] AArch64: Improve A64FX memset for remaining bytes + +Simplify handling of remaining bytes. Avoid lots of taken branches and complex +whilelo computations, instead unconditionally write vectors from the end. + +Reviewed-by: Naohiro Tamura +--- + sysdeps/aarch64/multiarch/memset_a64fx.S | 46 +++++++----------------- + 1 file changed, 13 insertions(+), 33 deletions(-) + +diff --git a/sysdeps/aarch64/multiarch/memset_a64fx.S b/sysdeps/aarch64/multiarch/memset_a64fx.S +index 75cf43ae79..337c86be6f 100644 +--- a/sysdeps/aarch64/multiarch/memset_a64fx.S ++++ b/sysdeps/aarch64/multiarch/memset_a64fx.S +@@ -130,38 +130,19 @@ L(unroll8): + b 1b + + L(last): +- whilelo p0.b, xzr, rest +- whilelo p1.b, vector_length, rest +- b.last 1f +- st1b z0.b, p0, [dst, #0, mul vl] +- st1b z0.b, p1, [dst, #1, mul vl] +- ret +-1: lsl tmp1, vector_length, 1 // vector_length * 2 +- whilelo p2.b, tmp1, rest +- incb tmp1 +- whilelo p3.b, tmp1, rest +- b.last 1f +- st1b z0.b, p0, [dst, #0, mul vl] +- st1b z0.b, p1, [dst, #1, mul vl] +- st1b z0.b, p2, [dst, #2, mul vl] +- st1b z0.b, p3, [dst, #3, mul vl] +- ret +-1: lsl tmp1, vector_length, 2 // vector_length * 4 +- whilelo p4.b, tmp1, rest +- incb tmp1 +- whilelo p5.b, tmp1, rest +- incb tmp1 +- whilelo p6.b, tmp1, rest +- incb tmp1 +- whilelo p7.b, tmp1, rest +- st1b z0.b, p0, [dst, #0, mul vl] +- st1b z0.b, p1, [dst, #1, mul vl] +- st1b z0.b, p2, [dst, #2, mul vl] +- st1b z0.b, p3, [dst, #3, mul vl] +- st1b z0.b, p4, [dst, #4, mul vl] +- st1b z0.b, p5, [dst, #5, mul vl] +- st1b z0.b, p6, [dst, #6, mul vl] +- st1b z0.b, p7, [dst, #7, mul vl] ++ cmp count, vector_length, lsl 1 ++ b.ls 2f ++ add tmp2, vector_length, vector_length, lsl 2 ++ cmp count, tmp2 ++ b.ls 5f ++ st1b z0.b, p0, [dstend, -8, mul vl] ++ st1b z0.b, p0, [dstend, -7, mul vl] ++ st1b z0.b, p0, [dstend, -6, mul vl] ++5: st1b z0.b, p0, [dstend, -5, mul vl] ++ st1b z0.b, p0, [dstend, -4, mul vl] ++ st1b z0.b, p0, [dstend, -3, mul vl] ++2: st1b z0.b, p0, [dstend, -2, mul vl] ++ st1b z0.b, p0, [dstend, -1, mul vl] + ret + + L(L1_prefetch): // if rest >= L1_SIZE +@@ -199,7 +180,6 @@ L(L2): + subs count, count, CACHE_LINE_SIZE + b.hi 1b + add count, count, CACHE_LINE_SIZE +- add dst, dst, CACHE_LINE_SIZE + b L(last) + + END (MEMSET) +-- +2.31.1 + diff --git a/SOURCES/glibc-rh2037416-4.patch b/SOURCES/glibc-rh2037416-4.patch new file mode 100644 index 0000000..e057eeb --- /dev/null +++ b/SOURCES/glibc-rh2037416-4.patch @@ -0,0 +1,51 @@ +From e69d9981f858a38e19304e6ff5ebdf89f2cb0ba0 Mon Sep 17 00:00:00 2001 +From: Wilco Dijkstra +Date: Tue, 10 Aug 2021 13:44:27 +0100 +Subject: [PATCH] [4/5] AArch64: Improve A64FX memset by removing unroll32 + +Remove unroll32 code since it doesn't improve performance. + +Reviewed-by: Naohiro Tamura +--- + sysdeps/aarch64/multiarch/memset_a64fx.S | 18 +----------------- + 1 file changed, 1 insertion(+), 17 deletions(-) + +diff --git a/sysdeps/aarch64/multiarch/memset_a64fx.S b/sysdeps/aarch64/multiarch/memset_a64fx.S +index 337c86be6f..ef0315658a 100644 +--- a/sysdeps/aarch64/multiarch/memset_a64fx.S ++++ b/sysdeps/aarch64/multiarch/memset_a64fx.S +@@ -102,22 +102,6 @@ L(vl_agnostic): // VL Agnostic + ccmp vector_length, tmp1, 0, cs + b.eq L(L1_prefetch) + +-L(unroll32): +- lsl tmp1, vector_length, 3 // vector_length * 8 +- lsl tmp2, vector_length, 5 // vector_length * 32 +- .p2align 3 +-1: cmp rest, tmp2 +- b.cc L(unroll8) +- st1b_unroll +- add dst, dst, tmp1 +- st1b_unroll +- add dst, dst, tmp1 +- st1b_unroll +- add dst, dst, tmp1 +- st1b_unroll +- add dst, dst, tmp1 +- sub rest, rest, tmp2 +- b 1b + + L(unroll8): + lsl tmp1, vector_length, 3 +@@ -155,7 +139,7 @@ L(L1_prefetch): // if rest >= L1_SIZE + sub rest, rest, CACHE_LINE_SIZE * 2 + cmp rest, L1_SIZE + b.ge 1b +- cbnz rest, L(unroll32) ++ cbnz rest, L(unroll8) + ret + + // count >= L2_SIZE +-- +2.31.1 + diff --git a/SOURCES/glibc-rh2037416-5.patch b/SOURCES/glibc-rh2037416-5.patch new file mode 100644 index 0000000..c92c2cf --- /dev/null +++ b/SOURCES/glibc-rh2037416-5.patch @@ -0,0 +1,96 @@ +From a5db6a5cae6a92d1675c013e5c8d972768721576 Mon Sep 17 00:00:00 2001 +From: Wilco Dijkstra +Date: Tue, 10 Aug 2021 13:46:20 +0100 +Subject: [PATCH] [5/5] AArch64: Improve A64FX memset medium loops + +Simplify the code for memsets smaller than L1. Improve the unroll8 and +L1_prefetch loops. + +Reviewed-by: Naohiro Tamura +--- + sysdeps/aarch64/multiarch/memset_a64fx.S | 45 ++++++++++-------------- + 1 file changed, 19 insertions(+), 26 deletions(-) + +diff --git a/sysdeps/aarch64/multiarch/memset_a64fx.S b/sysdeps/aarch64/multiarch/memset_a64fx.S +index ef0315658a..7bf759b6a7 100644 +--- a/sysdeps/aarch64/multiarch/memset_a64fx.S ++++ b/sysdeps/aarch64/multiarch/memset_a64fx.S +@@ -30,7 +30,6 @@ + #define L2_SIZE (8*1024*1024) // L2 8MB + #define CACHE_LINE_SIZE 256 + #define PF_DIST_L1 (CACHE_LINE_SIZE * 16) // Prefetch distance L1 +-#define rest x2 + #define vector_length x9 + + #if HAVE_AARCH64_SVE_ASM +@@ -89,29 +88,19 @@ ENTRY (MEMSET) + + .p2align 4 + L(vl_agnostic): // VL Agnostic +- mov rest, count + mov dst, dstin +- add dstend, dstin, count +- // if rest >= L2_SIZE && vector_length == 64 then L(L2) +- mov tmp1, 64 +- cmp rest, L2_SIZE +- ccmp vector_length, tmp1, 0, cs +- b.eq L(L2) +- // if rest >= L1_SIZE && vector_length == 64 then L(L1_prefetch) +- cmp rest, L1_SIZE +- ccmp vector_length, tmp1, 0, cs +- b.eq L(L1_prefetch) +- ++ cmp count, L1_SIZE ++ b.hi L(L1_prefetch) + ++ // count >= 8 * vector_length + L(unroll8): +- lsl tmp1, vector_length, 3 +- .p2align 3 +-1: cmp rest, tmp1 +- b.cc L(last) +- st1b_unroll ++ sub count, count, tmp1 ++ .p2align 4 ++1: st1b_unroll 0, 7 + add dst, dst, tmp1 +- sub rest, rest, tmp1 +- b 1b ++ subs count, count, tmp1 ++ b.hi 1b ++ add count, count, tmp1 + + L(last): + cmp count, vector_length, lsl 1 +@@ -129,18 +118,22 @@ L(last): + st1b z0.b, p0, [dstend, -1, mul vl] + ret + +-L(L1_prefetch): // if rest >= L1_SIZE ++ // count >= L1_SIZE + .p2align 3 ++L(L1_prefetch): ++ cmp count, L2_SIZE ++ b.hs L(L2) ++ cmp vector_length, 64 ++ b.ne L(unroll8) + 1: st1b_unroll 0, 3 + prfm pstl1keep, [dst, PF_DIST_L1] + st1b_unroll 4, 7 + prfm pstl1keep, [dst, PF_DIST_L1 + CACHE_LINE_SIZE] + add dst, dst, CACHE_LINE_SIZE * 2 +- sub rest, rest, CACHE_LINE_SIZE * 2 +- cmp rest, L1_SIZE +- b.ge 1b +- cbnz rest, L(unroll8) +- ret ++ sub count, count, CACHE_LINE_SIZE * 2 ++ cmp count, PF_DIST_L1 ++ b.hs 1b ++ b L(unroll8) + + // count >= L2_SIZE + .p2align 3 +-- +2.31.1 + diff --git a/SOURCES/glibc-rh2037416-6.patch b/SOURCES/glibc-rh2037416-6.patch new file mode 100644 index 0000000..b2522ad --- /dev/null +++ b/SOURCES/glibc-rh2037416-6.patch @@ -0,0 +1,39 @@ +From 1d9f99ce1b3788d1897cb53a76d57e973111b8fe Mon Sep 17 00:00:00 2001 +From: Naohiro Tamura +Date: Fri, 27 Aug 2021 05:03:04 +0000 +Subject: [PATCH] AArch64: Update A64FX memset not to degrade at 16KB + +This patch updates unroll8 code so as not to degrade at the peak +performance 16KB for both FX1000 and FX700. + +Inserted 2 instructions at the beginning of the unroll8 loop, +cmp and branch, are a workaround that is found heuristically. + +Reviewed-by: Wilco Dijkstra +--- + sysdeps/aarch64/multiarch/memset_a64fx.S | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/sysdeps/aarch64/multiarch/memset_a64fx.S b/sysdeps/aarch64/multiarch/memset_a64fx.S +index 7bf759b6a7..f7dfdaace7 100644 +--- a/sysdeps/aarch64/multiarch/memset_a64fx.S ++++ b/sysdeps/aarch64/multiarch/memset_a64fx.S +@@ -96,7 +96,14 @@ L(vl_agnostic): // VL Agnostic + L(unroll8): + sub count, count, tmp1 + .p2align 4 +-1: st1b_unroll 0, 7 ++ // The 2 instructions at the beginning of the following loop, ++ // cmp and branch, are a workaround so as not to degrade at ++ // the peak performance 16KB. ++ // It is found heuristically and the branch condition, b.ne, ++ // is chosen intentionally never to jump. ++1: cmp xzr, xzr ++ b.ne 1b ++ st1b_unroll 0, 7 + add dst, dst, tmp1 + subs count, count, tmp1 + b.hi 1b +-- +2.31.1 + diff --git a/SOURCES/glibc-rh2037416-7.patch b/SOURCES/glibc-rh2037416-7.patch new file mode 100644 index 0000000..e57fef7 --- /dev/null +++ b/SOURCES/glibc-rh2037416-7.patch @@ -0,0 +1,32 @@ +From 381b29616abb82babc8163bdf516c6da87544b35 Mon Sep 17 00:00:00 2001 +From: Naohiro Tamura +Date: Fri, 24 Sep 2021 07:49:59 +0000 +Subject: [PATCH] aarch64: Disable A64FX memcpy/memmove BTI unconditionally + +This patch disables A64FX memcpy/memmove BTI instruction insertion +unconditionally such as A64FX memset patch [1] for performance. + +[1] commit 07b427296b8d59f439144029d9a948f6c1ce0a31 + +Reviewed-by: Szabolcs Nagy +--- + sysdeps/aarch64/multiarch/memcpy_a64fx.S | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sysdeps/aarch64/multiarch/memcpy_a64fx.S b/sysdeps/aarch64/multiarch/memcpy_a64fx.S +index 65528405bb..ae7464e09f 100644 +--- a/sysdeps/aarch64/multiarch/memcpy_a64fx.S ++++ b/sysdeps/aarch64/multiarch/memcpy_a64fx.S +@@ -19,6 +19,9 @@ + + #include + ++#undef BTI_C ++#define BTI_C ++ + /* Assumptions: + * + * ARMv8.2-a, AArch64, unaligned accesses, sve +-- +2.31.1 + diff --git a/SOURCES/glibc-rh2037416-8.patch b/SOURCES/glibc-rh2037416-8.patch new file mode 100644 index 0000000..6a68332 --- /dev/null +++ b/SOURCES/glibc-rh2037416-8.patch @@ -0,0 +1,630 @@ +From b31bd11454fade731e5158b1aea40b133ae19926 Mon Sep 17 00:00:00 2001 +From: Wilco Dijkstra +Date: Thu, 2 Dec 2021 18:33:26 +0000 +Subject: [PATCH] AArch64: Improve A64FX memcpy + +v2 is a complete rewrite of the A64FX memcpy. Performance is improved +by streamlining the code, aligning all large copies and using a single +unrolled loop for all sizes. The code size for memcpy and memmove goes +down from 1796 bytes to 868 bytes. Performance is better in all cases: +bench-memcpy-random is 2.3% faster overall, bench-memcpy-large is ~33% +faster for large sizes, bench-memcpy-walk is 25% faster for small sizes +and 20% for the largest sizes. The geomean of all tests in bench-memcpy +is 5.1% faster, and total time is reduced by 4%. + +Reviewed-by: Szabolcs Nagy +--- + sysdeps/aarch64/multiarch/memcpy_a64fx.S | 546 ++++++++++------------- + 1 file changed, 225 insertions(+), 321 deletions(-) + +diff --git a/sysdeps/aarch64/multiarch/memcpy_a64fx.S b/sysdeps/aarch64/multiarch/memcpy_a64fx.S +index ae7464e09f..0b306925e6 100644 +--- a/sysdeps/aarch64/multiarch/memcpy_a64fx.S ++++ b/sysdeps/aarch64/multiarch/memcpy_a64fx.S +@@ -28,20 +28,15 @@ + * + */ + +-#define L2_SIZE (8*1024*1024)/2 // L2 8MB/2 +-#define CACHE_LINE_SIZE 256 +-#define ZF_DIST (CACHE_LINE_SIZE * 21) // Zerofill distance +-#define dest x0 +-#define src x1 +-#define n x2 // size +-#define tmp1 x3 +-#define tmp2 x4 +-#define tmp3 x5 +-#define rest x6 +-#define dest_ptr x7 +-#define src_ptr x8 +-#define vector_length x9 +-#define cl_remainder x10 // CACHE_LINE_SIZE remainder ++#define dstin x0 ++#define src x1 ++#define n x2 ++#define dst x3 ++#define dstend x4 ++#define srcend x5 ++#define tmp x6 ++#define vlen x7 ++#define vlen8 x8 + + #if HAVE_AARCH64_SVE_ASM + # if IS_IN (libc) +@@ -50,45 +45,37 @@ + + .arch armv8.2-a+sve + +- .macro dc_zva times +- dc zva, tmp1 +- add tmp1, tmp1, CACHE_LINE_SIZE +- .if \times-1 +- dc_zva "(\times-1)" +- .endif +- .endm +- + .macro ld1b_unroll8 +- ld1b z0.b, p0/z, [src_ptr, #0, mul vl] +- ld1b z1.b, p0/z, [src_ptr, #1, mul vl] +- ld1b z2.b, p0/z, [src_ptr, #2, mul vl] +- ld1b z3.b, p0/z, [src_ptr, #3, mul vl] +- ld1b z4.b, p0/z, [src_ptr, #4, mul vl] +- ld1b z5.b, p0/z, [src_ptr, #5, mul vl] +- ld1b z6.b, p0/z, [src_ptr, #6, mul vl] +- ld1b z7.b, p0/z, [src_ptr, #7, mul vl] ++ ld1b z0.b, p0/z, [src, 0, mul vl] ++ ld1b z1.b, p0/z, [src, 1, mul vl] ++ ld1b z2.b, p0/z, [src, 2, mul vl] ++ ld1b z3.b, p0/z, [src, 3, mul vl] ++ ld1b z4.b, p0/z, [src, 4, mul vl] ++ ld1b z5.b, p0/z, [src, 5, mul vl] ++ ld1b z6.b, p0/z, [src, 6, mul vl] ++ ld1b z7.b, p0/z, [src, 7, mul vl] + .endm + + .macro stld1b_unroll4a +- st1b z0.b, p0, [dest_ptr, #0, mul vl] +- st1b z1.b, p0, [dest_ptr, #1, mul vl] +- ld1b z0.b, p0/z, [src_ptr, #0, mul vl] +- ld1b z1.b, p0/z, [src_ptr, #1, mul vl] +- st1b z2.b, p0, [dest_ptr, #2, mul vl] +- st1b z3.b, p0, [dest_ptr, #3, mul vl] +- ld1b z2.b, p0/z, [src_ptr, #2, mul vl] +- ld1b z3.b, p0/z, [src_ptr, #3, mul vl] ++ st1b z0.b, p0, [dst, 0, mul vl] ++ st1b z1.b, p0, [dst, 1, mul vl] ++ ld1b z0.b, p0/z, [src, 0, mul vl] ++ ld1b z1.b, p0/z, [src, 1, mul vl] ++ st1b z2.b, p0, [dst, 2, mul vl] ++ st1b z3.b, p0, [dst, 3, mul vl] ++ ld1b z2.b, p0/z, [src, 2, mul vl] ++ ld1b z3.b, p0/z, [src, 3, mul vl] + .endm + + .macro stld1b_unroll4b +- st1b z4.b, p0, [dest_ptr, #4, mul vl] +- st1b z5.b, p0, [dest_ptr, #5, mul vl] +- ld1b z4.b, p0/z, [src_ptr, #4, mul vl] +- ld1b z5.b, p0/z, [src_ptr, #5, mul vl] +- st1b z6.b, p0, [dest_ptr, #6, mul vl] +- st1b z7.b, p0, [dest_ptr, #7, mul vl] +- ld1b z6.b, p0/z, [src_ptr, #6, mul vl] +- ld1b z7.b, p0/z, [src_ptr, #7, mul vl] ++ st1b z4.b, p0, [dst, 4, mul vl] ++ st1b z5.b, p0, [dst, 5, mul vl] ++ ld1b z4.b, p0/z, [src, 4, mul vl] ++ ld1b z5.b, p0/z, [src, 5, mul vl] ++ st1b z6.b, p0, [dst, 6, mul vl] ++ st1b z7.b, p0, [dst, 7, mul vl] ++ ld1b z6.b, p0/z, [src, 6, mul vl] ++ ld1b z7.b, p0/z, [src, 7, mul vl] + .endm + + .macro stld1b_unroll8 +@@ -97,87 +84,18 @@ + .endm + + .macro st1b_unroll8 +- st1b z0.b, p0, [dest_ptr, #0, mul vl] +- st1b z1.b, p0, [dest_ptr, #1, mul vl] +- st1b z2.b, p0, [dest_ptr, #2, mul vl] +- st1b z3.b, p0, [dest_ptr, #3, mul vl] +- st1b z4.b, p0, [dest_ptr, #4, mul vl] +- st1b z5.b, p0, [dest_ptr, #5, mul vl] +- st1b z6.b, p0, [dest_ptr, #6, mul vl] +- st1b z7.b, p0, [dest_ptr, #7, mul vl] ++ st1b z0.b, p0, [dst, 0, mul vl] ++ st1b z1.b, p0, [dst, 1, mul vl] ++ st1b z2.b, p0, [dst, 2, mul vl] ++ st1b z3.b, p0, [dst, 3, mul vl] ++ st1b z4.b, p0, [dst, 4, mul vl] ++ st1b z5.b, p0, [dst, 5, mul vl] ++ st1b z6.b, p0, [dst, 6, mul vl] ++ st1b z7.b, p0, [dst, 7, mul vl] + .endm + +- .macro shortcut_for_small_size exit +- // if rest <= vector_length * 2 +- whilelo p0.b, xzr, n +- whilelo p1.b, vector_length, n +- b.last 1f +- ld1b z0.b, p0/z, [src, #0, mul vl] +- ld1b z1.b, p1/z, [src, #1, mul vl] +- st1b z0.b, p0, [dest, #0, mul vl] +- st1b z1.b, p1, [dest, #1, mul vl] +- ret +-1: // if rest > vector_length * 8 +- cmp n, vector_length, lsl 3 // vector_length * 8 +- b.hi \exit +- // if rest <= vector_length * 4 +- lsl tmp1, vector_length, 1 // vector_length * 2 +- whilelo p2.b, tmp1, n +- incb tmp1 +- whilelo p3.b, tmp1, n +- b.last 1f +- ld1b z0.b, p0/z, [src, #0, mul vl] +- ld1b z1.b, p1/z, [src, #1, mul vl] +- ld1b z2.b, p2/z, [src, #2, mul vl] +- ld1b z3.b, p3/z, [src, #3, mul vl] +- st1b z0.b, p0, [dest, #0, mul vl] +- st1b z1.b, p1, [dest, #1, mul vl] +- st1b z2.b, p2, [dest, #2, mul vl] +- st1b z3.b, p3, [dest, #3, mul vl] +- ret +-1: // if rest <= vector_length * 8 +- lsl tmp1, vector_length, 2 // vector_length * 4 +- whilelo p4.b, tmp1, n +- incb tmp1 +- whilelo p5.b, tmp1, n +- b.last 1f +- ld1b z0.b, p0/z, [src, #0, mul vl] +- ld1b z1.b, p1/z, [src, #1, mul vl] +- ld1b z2.b, p2/z, [src, #2, mul vl] +- ld1b z3.b, p3/z, [src, #3, mul vl] +- ld1b z4.b, p4/z, [src, #4, mul vl] +- ld1b z5.b, p5/z, [src, #5, mul vl] +- st1b z0.b, p0, [dest, #0, mul vl] +- st1b z1.b, p1, [dest, #1, mul vl] +- st1b z2.b, p2, [dest, #2, mul vl] +- st1b z3.b, p3, [dest, #3, mul vl] +- st1b z4.b, p4, [dest, #4, mul vl] +- st1b z5.b, p5, [dest, #5, mul vl] +- ret +-1: lsl tmp1, vector_length, 2 // vector_length * 4 +- incb tmp1 // vector_length * 5 +- incb tmp1 // vector_length * 6 +- whilelo p6.b, tmp1, n +- incb tmp1 +- whilelo p7.b, tmp1, n +- ld1b z0.b, p0/z, [src, #0, mul vl] +- ld1b z1.b, p1/z, [src, #1, mul vl] +- ld1b z2.b, p2/z, [src, #2, mul vl] +- ld1b z3.b, p3/z, [src, #3, mul vl] +- ld1b z4.b, p4/z, [src, #4, mul vl] +- ld1b z5.b, p5/z, [src, #5, mul vl] +- ld1b z6.b, p6/z, [src, #6, mul vl] +- ld1b z7.b, p7/z, [src, #7, mul vl] +- st1b z0.b, p0, [dest, #0, mul vl] +- st1b z1.b, p1, [dest, #1, mul vl] +- st1b z2.b, p2, [dest, #2, mul vl] +- st1b z3.b, p3, [dest, #3, mul vl] +- st1b z4.b, p4, [dest, #4, mul vl] +- st1b z5.b, p5, [dest, #5, mul vl] +- st1b z6.b, p6, [dest, #6, mul vl] +- st1b z7.b, p7, [dest, #7, mul vl] +- ret +- .endm ++#undef BTI_C ++#define BTI_C + + ENTRY (MEMCPY) + +@@ -185,223 +103,209 @@ ENTRY (MEMCPY) + PTR_ARG (1) + SIZE_ARG (2) + +-L(memcpy): +- cntb vector_length +- // shortcut for less than vector_length * 8 +- // gives a free ptrue to p0.b for n >= vector_length +- shortcut_for_small_size L(vl_agnostic) +- // end of shortcut +- +-L(vl_agnostic): // VL Agnostic +- mov rest, n +- mov dest_ptr, dest +- mov src_ptr, src +- // if rest >= L2_SIZE && vector_length == 64 then L(L2) +- mov tmp1, 64 +- cmp rest, L2_SIZE +- ccmp vector_length, tmp1, 0, cs +- b.eq L(L2) +- +-L(unroll8): // unrolling and software pipeline +- lsl tmp1, vector_length, 3 // vector_length * 8 +- .p2align 3 +- cmp rest, tmp1 +- b.cc L(last) ++ cntb vlen ++ cmp n, vlen, lsl 1 ++ b.hi L(copy_small) ++ whilelo p1.b, vlen, n ++ whilelo p0.b, xzr, n ++ ld1b z0.b, p0/z, [src, 0, mul vl] ++ ld1b z1.b, p1/z, [src, 1, mul vl] ++ st1b z0.b, p0, [dstin, 0, mul vl] ++ st1b z1.b, p1, [dstin, 1, mul vl] ++ ret ++ ++ .p2align 4 ++ ++L(copy_small): ++ cmp n, vlen, lsl 3 ++ b.hi L(copy_large) ++ add dstend, dstin, n ++ add srcend, src, n ++ cmp n, vlen, lsl 2 ++ b.hi 1f ++ ++ /* Copy 2-4 vectors. */ ++ ptrue p0.b ++ ld1b z0.b, p0/z, [src, 0, mul vl] ++ ld1b z1.b, p0/z, [src, 1, mul vl] ++ ld1b z2.b, p0/z, [srcend, -2, mul vl] ++ ld1b z3.b, p0/z, [srcend, -1, mul vl] ++ st1b z0.b, p0, [dstin, 0, mul vl] ++ st1b z1.b, p0, [dstin, 1, mul vl] ++ st1b z2.b, p0, [dstend, -2, mul vl] ++ st1b z3.b, p0, [dstend, -1, mul vl] ++ ret ++ ++ .p2align 4 ++ /* Copy 4-8 vectors. */ ++1: ptrue p0.b ++ ld1b z0.b, p0/z, [src, 0, mul vl] ++ ld1b z1.b, p0/z, [src, 1, mul vl] ++ ld1b z2.b, p0/z, [src, 2, mul vl] ++ ld1b z3.b, p0/z, [src, 3, mul vl] ++ ld1b z4.b, p0/z, [srcend, -4, mul vl] ++ ld1b z5.b, p0/z, [srcend, -3, mul vl] ++ ld1b z6.b, p0/z, [srcend, -2, mul vl] ++ ld1b z7.b, p0/z, [srcend, -1, mul vl] ++ st1b z0.b, p0, [dstin, 0, mul vl] ++ st1b z1.b, p0, [dstin, 1, mul vl] ++ st1b z2.b, p0, [dstin, 2, mul vl] ++ st1b z3.b, p0, [dstin, 3, mul vl] ++ st1b z4.b, p0, [dstend, -4, mul vl] ++ st1b z5.b, p0, [dstend, -3, mul vl] ++ st1b z6.b, p0, [dstend, -2, mul vl] ++ st1b z7.b, p0, [dstend, -1, mul vl] ++ ret ++ ++ .p2align 4 ++ /* At least 8 vectors - always align to vector length for ++ higher and consistent write performance. */ ++L(copy_large): ++ sub tmp, vlen, 1 ++ and tmp, dstin, tmp ++ sub tmp, vlen, tmp ++ whilelo p1.b, xzr, tmp ++ ld1b z1.b, p1/z, [src] ++ st1b z1.b, p1, [dstin] ++ add dst, dstin, tmp ++ add src, src, tmp ++ sub n, n, tmp ++ ptrue p0.b ++ ++ lsl vlen8, vlen, 3 ++ subs n, n, vlen8 ++ b.ls 3f + ld1b_unroll8 +- add src_ptr, src_ptr, tmp1 +- sub rest, rest, tmp1 +- cmp rest, tmp1 +- b.cc 2f +- .p2align 3 ++ add src, src, vlen8 ++ subs n, n, vlen8 ++ b.ls 2f ++ ++ .p2align 4 ++ /* 8x unrolled and software pipelined loop. */ + 1: stld1b_unroll8 +- add dest_ptr, dest_ptr, tmp1 +- add src_ptr, src_ptr, tmp1 +- sub rest, rest, tmp1 +- cmp rest, tmp1 +- b.ge 1b ++ add dst, dst, vlen8 ++ add src, src, vlen8 ++ subs n, n, vlen8 ++ b.hi 1b + 2: st1b_unroll8 +- add dest_ptr, dest_ptr, tmp1 +- +- .p2align 3 +-L(last): +- whilelo p0.b, xzr, rest +- whilelo p1.b, vector_length, rest +- b.last 1f +- ld1b z0.b, p0/z, [src_ptr, #0, mul vl] +- ld1b z1.b, p1/z, [src_ptr, #1, mul vl] +- st1b z0.b, p0, [dest_ptr, #0, mul vl] +- st1b z1.b, p1, [dest_ptr, #1, mul vl] +- ret +-1: lsl tmp1, vector_length, 1 // vector_length * 2 +- whilelo p2.b, tmp1, rest +- incb tmp1 +- whilelo p3.b, tmp1, rest +- b.last 1f +- ld1b z0.b, p0/z, [src_ptr, #0, mul vl] +- ld1b z1.b, p1/z, [src_ptr, #1, mul vl] +- ld1b z2.b, p2/z, [src_ptr, #2, mul vl] +- ld1b z3.b, p3/z, [src_ptr, #3, mul vl] +- st1b z0.b, p0, [dest_ptr, #0, mul vl] +- st1b z1.b, p1, [dest_ptr, #1, mul vl] +- st1b z2.b, p2, [dest_ptr, #2, mul vl] +- st1b z3.b, p3, [dest_ptr, #3, mul vl] ++ add dst, dst, vlen8 ++3: add n, n, vlen8 ++ ++ /* Move last 0-8 vectors. */ ++L(last_bytes): ++ cmp n, vlen, lsl 1 ++ b.hi 1f ++ whilelo p0.b, xzr, n ++ whilelo p1.b, vlen, n ++ ld1b z0.b, p0/z, [src, 0, mul vl] ++ ld1b z1.b, p1/z, [src, 1, mul vl] ++ st1b z0.b, p0, [dst, 0, mul vl] ++ st1b z1.b, p1, [dst, 1, mul vl] + ret +-1: lsl tmp1, vector_length, 2 // vector_length * 4 +- whilelo p4.b, tmp1, rest +- incb tmp1 +- whilelo p5.b, tmp1, rest +- incb tmp1 +- whilelo p6.b, tmp1, rest +- incb tmp1 +- whilelo p7.b, tmp1, rest +- ld1b z0.b, p0/z, [src_ptr, #0, mul vl] +- ld1b z1.b, p1/z, [src_ptr, #1, mul vl] +- ld1b z2.b, p2/z, [src_ptr, #2, mul vl] +- ld1b z3.b, p3/z, [src_ptr, #3, mul vl] +- ld1b z4.b, p4/z, [src_ptr, #4, mul vl] +- ld1b z5.b, p5/z, [src_ptr, #5, mul vl] +- ld1b z6.b, p6/z, [src_ptr, #6, mul vl] +- ld1b z7.b, p7/z, [src_ptr, #7, mul vl] +- st1b z0.b, p0, [dest_ptr, #0, mul vl] +- st1b z1.b, p1, [dest_ptr, #1, mul vl] +- st1b z2.b, p2, [dest_ptr, #2, mul vl] +- st1b z3.b, p3, [dest_ptr, #3, mul vl] +- st1b z4.b, p4, [dest_ptr, #4, mul vl] +- st1b z5.b, p5, [dest_ptr, #5, mul vl] +- st1b z6.b, p6, [dest_ptr, #6, mul vl] +- st1b z7.b, p7, [dest_ptr, #7, mul vl] ++ ++ .p2align 4 ++ ++1: add srcend, src, n ++ add dstend, dst, n ++ ld1b z0.b, p0/z, [src, 0, mul vl] ++ ld1b z1.b, p0/z, [src, 1, mul vl] ++ ld1b z2.b, p0/z, [srcend, -2, mul vl] ++ ld1b z3.b, p0/z, [srcend, -1, mul vl] ++ cmp n, vlen, lsl 2 ++ b.hi 1f ++ ++ st1b z0.b, p0, [dst, 0, mul vl] ++ st1b z1.b, p0, [dst, 1, mul vl] ++ st1b z2.b, p0, [dstend, -2, mul vl] ++ st1b z3.b, p0, [dstend, -1, mul vl] + ret + +-L(L2): +- // align dest address at CACHE_LINE_SIZE byte boundary +- mov tmp1, CACHE_LINE_SIZE +- ands tmp2, dest_ptr, CACHE_LINE_SIZE - 1 +- // if cl_remainder == 0 +- b.eq L(L2_dc_zva) +- sub cl_remainder, tmp1, tmp2 +- // process remainder until the first CACHE_LINE_SIZE boundary +- whilelo p1.b, xzr, cl_remainder // keep p0.b all true +- whilelo p2.b, vector_length, cl_remainder +- b.last 1f +- ld1b z1.b, p1/z, [src_ptr, #0, mul vl] +- ld1b z2.b, p2/z, [src_ptr, #1, mul vl] +- st1b z1.b, p1, [dest_ptr, #0, mul vl] +- st1b z2.b, p2, [dest_ptr, #1, mul vl] +- b 2f +-1: lsl tmp1, vector_length, 1 // vector_length * 2 +- whilelo p3.b, tmp1, cl_remainder +- incb tmp1 +- whilelo p4.b, tmp1, cl_remainder +- ld1b z1.b, p1/z, [src_ptr, #0, mul vl] +- ld1b z2.b, p2/z, [src_ptr, #1, mul vl] +- ld1b z3.b, p3/z, [src_ptr, #2, mul vl] +- ld1b z4.b, p4/z, [src_ptr, #3, mul vl] +- st1b z1.b, p1, [dest_ptr, #0, mul vl] +- st1b z2.b, p2, [dest_ptr, #1, mul vl] +- st1b z3.b, p3, [dest_ptr, #2, mul vl] +- st1b z4.b, p4, [dest_ptr, #3, mul vl] +-2: add dest_ptr, dest_ptr, cl_remainder +- add src_ptr, src_ptr, cl_remainder +- sub rest, rest, cl_remainder +- +-L(L2_dc_zva): +- // zero fill +- and tmp1, dest, 0xffffffffffffff +- and tmp2, src, 0xffffffffffffff +- subs tmp1, tmp1, tmp2 // diff +- b.ge 1f +- neg tmp1, tmp1 +-1: mov tmp3, ZF_DIST + CACHE_LINE_SIZE * 2 +- cmp tmp1, tmp3 +- b.lo L(unroll8) +- mov tmp1, dest_ptr +- dc_zva (ZF_DIST / CACHE_LINE_SIZE) - 1 +- // unroll +- ld1b_unroll8 // this line has to be after "b.lo L(unroll8)" +- add src_ptr, src_ptr, CACHE_LINE_SIZE * 2 +- sub rest, rest, CACHE_LINE_SIZE * 2 +- mov tmp1, ZF_DIST +- .p2align 3 +-1: stld1b_unroll4a +- add tmp2, dest_ptr, tmp1 // dest_ptr + ZF_DIST +- dc zva, tmp2 +- stld1b_unroll4b +- add tmp2, tmp2, CACHE_LINE_SIZE +- dc zva, tmp2 +- add dest_ptr, dest_ptr, CACHE_LINE_SIZE * 2 +- add src_ptr, src_ptr, CACHE_LINE_SIZE * 2 +- sub rest, rest, CACHE_LINE_SIZE * 2 +- cmp rest, tmp3 // ZF_DIST + CACHE_LINE_SIZE * 2 +- b.ge 1b +- st1b_unroll8 +- add dest_ptr, dest_ptr, CACHE_LINE_SIZE * 2 +- b L(unroll8) ++1: ld1b z4.b, p0/z, [src, 2, mul vl] ++ ld1b z5.b, p0/z, [src, 3, mul vl] ++ ld1b z6.b, p0/z, [srcend, -4, mul vl] ++ ld1b z7.b, p0/z, [srcend, -3, mul vl] ++ st1b z0.b, p0, [dst, 0, mul vl] ++ st1b z1.b, p0, [dst, 1, mul vl] ++ st1b z4.b, p0, [dst, 2, mul vl] ++ st1b z5.b, p0, [dst, 3, mul vl] ++ st1b z6.b, p0, [dstend, -4, mul vl] ++ st1b z7.b, p0, [dstend, -3, mul vl] ++ st1b z2.b, p0, [dstend, -2, mul vl] ++ st1b z3.b, p0, [dstend, -1, mul vl] ++ ret + + END (MEMCPY) + libc_hidden_builtin_def (MEMCPY) + + +-ENTRY (MEMMOVE) ++ENTRY_ALIGN (MEMMOVE, 4) + + PTR_ARG (0) + PTR_ARG (1) + SIZE_ARG (2) + +- // remove tag address +- // dest has to be immutable because it is the return value +- // src has to be immutable because it is used in L(bwd_last) +- and tmp2, dest, 0xffffffffffffff // save dest_notag into tmp2 +- and tmp3, src, 0xffffffffffffff // save src_notag intp tmp3 +- cmp n, 0 +- ccmp tmp2, tmp3, 4, ne +- b.ne 1f ++ /* Fast case for up to 2 vectors. */ ++ cntb vlen ++ cmp n, vlen, lsl 1 ++ b.hi 1f ++ whilelo p0.b, xzr, n ++ whilelo p1.b, vlen, n ++ ld1b z0.b, p0/z, [src, 0, mul vl] ++ ld1b z1.b, p1/z, [src, 1, mul vl] ++ st1b z0.b, p0, [dstin, 0, mul vl] ++ st1b z1.b, p1, [dstin, 1, mul vl] ++L(full_overlap): + ret +-1: cntb vector_length +- // shortcut for less than vector_length * 8 +- // gives a free ptrue to p0.b for n >= vector_length +- // tmp2 and tmp3 should not be used in this macro to keep +- // notag addresses +- shortcut_for_small_size L(dispatch) +- // end of shortcut +- +-L(dispatch): +- // tmp2 = dest_notag, tmp3 = src_notag +- // diff = dest_notag - src_notag +- sub tmp1, tmp2, tmp3 +- // if diff <= 0 || diff >= n then memcpy +- cmp tmp1, 0 +- ccmp tmp1, n, 2, gt +- b.cs L(vl_agnostic) +- +-L(bwd_start): +- mov rest, n +- add dest_ptr, dest, n // dest_end +- add src_ptr, src, n // src_end +- +-L(bwd_unroll8): // unrolling and software pipeline +- lsl tmp1, vector_length, 3 // vector_length * 8 +- .p2align 3 +- cmp rest, tmp1 +- b.cc L(bwd_last) +- sub src_ptr, src_ptr, tmp1 ++ ++ .p2align 4 ++ /* Check for overlapping moves. Return if there is a full overlap. ++ Small moves up to 8 vectors use the overlap-safe copy_small code. ++ Non-overlapping or overlapping moves with dst < src use memcpy. ++ Overlapping moves with dst > src use a backward copy loop. */ ++1: sub tmp, dstin, src ++ ands tmp, tmp, 0xffffffffffffff /* Clear special tag bits. */ ++ b.eq L(full_overlap) ++ cmp n, vlen, lsl 3 ++ b.ls L(copy_small) ++ cmp tmp, n ++ b.hs L(copy_large) ++ ++ /* Align to vector length. */ ++ add dst, dstin, n ++ sub tmp, vlen, 1 ++ ands tmp, dst, tmp ++ csel tmp, tmp, vlen, ne ++ whilelo p1.b, xzr, tmp ++ sub n, n, tmp ++ ld1b z1.b, p1/z, [src, n] ++ st1b z1.b, p1, [dstin, n] ++ add src, src, n ++ add dst, dstin, n ++ ++ ptrue p0.b ++ lsl vlen8, vlen, 3 ++ subs n, n, vlen8 ++ b.ls 3f ++ sub src, src, vlen8 + ld1b_unroll8 +- sub rest, rest, tmp1 +- cmp rest, tmp1 +- b.cc 2f +- .p2align 3 +-1: sub src_ptr, src_ptr, tmp1 +- sub dest_ptr, dest_ptr, tmp1 ++ subs n, n, vlen8 ++ b.ls 2f ++ ++ .p2align 4 ++ /* 8x unrolled and software pipelined backward copy loop. */ ++1: sub src, src, vlen8 ++ sub dst, dst, vlen8 + stld1b_unroll8 +- sub rest, rest, tmp1 +- cmp rest, tmp1 +- b.ge 1b +-2: sub dest_ptr, dest_ptr, tmp1 ++ subs n, n, vlen8 ++ b.hi 1b ++2: sub dst, dst, vlen8 + st1b_unroll8 ++3: add n, n, vlen8 + +-L(bwd_last): +- mov dest_ptr, dest +- mov src_ptr, src +- b L(last) ++ /* Adjust src/dst for last 0-8 vectors. */ ++ sub src, src, n ++ mov dst, dstin ++ b L(last_bytes) + + END (MEMMOVE) + libc_hidden_builtin_def (MEMMOVE) +-- +2.31.1 + diff --git a/SOURCES/glibc-rh2054790.patch b/SOURCES/glibc-rh2054790.patch new file mode 100644 index 0000000..6af769e --- /dev/null +++ b/SOURCES/glibc-rh2054790.patch @@ -0,0 +1,27 @@ +commit ea89d5bbd9e5e514b606045d909e6ab87d851c88 +Author: Arjun Shankar +Date: Thu Feb 24 21:43:09 2022 +0100 + + localedef: Handle symbolic links when generating locale-archive + + Whenever locale data for any locale included symbolic links, localedef + would throw the error "incomplete set of locale files" and exclude it + from the generated locale archive. This commit fixes that. + + Co-authored-by: Florian Weimer + + Reviewed-by: Carlos O'Donell + +diff --git a/locale/programs/locarchive.c b/locale/programs/locarchive.c +index dec73264563bc2a0..990f7eb6830d2e57 100644 +--- a/locale/programs/locarchive.c ++++ b/locale/programs/locarchive.c +@@ -1391,7 +1391,7 @@ add_locales_to_archive (size_t nlist, char *list[], bool replace) + { + char fullname[fnamelen + 2 * strlen (d->d_name) + 7]; + +- if (d_type == DT_UNKNOWN) ++ if (d_type == DT_UNKNOWN || d_type == DT_LNK) + { + strcpy (stpcpy (stpcpy (fullname, fname), "/"), + d->d_name); diff --git a/SOURCES/glibc-rh2063042.patch b/SOURCES/glibc-rh2063042.patch new file mode 100644 index 0000000..921add1 --- /dev/null +++ b/SOURCES/glibc-rh2063042.patch @@ -0,0 +1,358 @@ +commit fcfc9086815bf0d277ad47a90ee3fda4c37acca8 +Author: Siddhesh Poyarekar +Date: Wed Jan 12 23:34:48 2022 +0530 + + 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 + Reviewed-by: Adhemerval Zanella + +# Conflicts: +# debug/tst-fortify.c + +diff --git a/debug/Makefile b/debug/Makefile +index c92fd23dda1a7279..b0f0b7beb6d5cef5 100644 +--- a/debug/Makefile ++++ b/debug/Makefile +@@ -132,6 +132,12 @@ define cflags-lfs + CFLAGS-tst-fortify-$(1)-lfs-$(2).$(1) += -D_FILE_OFFSET_BITS=64 + 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 are testing. Disable that warning. They are also testing + # 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))) + $(objpfx)tst-fortify-$(1)-$(2)-$(3).$(1): tst-fortify.c Makefile + ( echo "/* Autogenerated from Makefile. */"; \ +- echo ""; \ ++ echo "$(src-chk-$(2))"; \ + echo "#include \"tst-fortify.c\"" ) > $$@.tmp + mv $$@.tmp $$@ + endef + + chk-extensions = c cc +-chk-types = default lfs ++chk-types = default lfs nongnu + chk-levels = 1 2 3 + + $(foreach e,$(chk-extensions), \ +diff --git a/debug/tst-fortify.c b/debug/tst-fortify.c +index 5e76081255316a93..1668294e48b5c63c 100644 +--- a/debug/tst-fortify.c ++++ b/debug/tst-fortify.c +@@ -1,4 +1,5 @@ +-/* Copyright (C) 2004-2018 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. + Contributed by Jakub Jelinek , 2004. + +@@ -37,6 +38,17 @@ + #include + #include + ++#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_free free +@@ -163,7 +175,7 @@ do_test (void) + if (memcmp (buf, "aabcdefghi", 10)) + FAIL (); + +- if (mempcpy (buf + 5, "abcde", 5) != buf + 10 ++ if (MEMPCPY (buf + 5, "abcde", 5) != buf + 5 + MEMPCPY_RET ("abcde") + || memcmp (buf, "aabcdabcde", 10)) + FAIL (); + +@@ -208,7 +220,7 @@ do_test (void) + if (memcmp (buf, "aabcdefghi", 10)) + 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)) + FAIL (); + +@@ -267,7 +279,8 @@ do_test (void) + if (memcmp (a.buf1, "aabcdefghi", 10)) + 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)) + FAIL (); + +@@ -348,6 +361,7 @@ do_test (void) + bcopy (buf + 1, buf + 2, l0 + 9); + CHK_FAIL_END + ++#ifdef _GNU_SOURCE + CHK_FAIL_START + p = (char *) mempcpy (buf + 6, "abcde", 5); + CHK_FAIL_END +@@ -355,6 +369,7 @@ do_test (void) + CHK_FAIL_START + p = (char *) mempcpy (buf + 6, "abcde", l0 + 5); + CHK_FAIL_END ++#endif + + CHK_FAIL_START + memset (buf + 9, 'j', 2); +@@ -465,6 +480,7 @@ do_test (void) + bcopy (a.buf1 + 1, a.buf1 + 2, l0 + 9); + CHK_FAIL_END + ++#ifdef _GNU_SOURCE + CHK_FAIL_START + p = (char *) mempcpy (a.buf1 + 6, "abcde", 5); + CHK_FAIL_END +@@ -472,6 +488,7 @@ do_test (void) + CHK_FAIL_START + p = (char *) mempcpy (a.buf1 + 6, "abcde", l0 + 5); + CHK_FAIL_END ++#endif + + CHK_FAIL_START + memset (a.buf1 + 9, 'j', 2); +@@ -551,7 +568,7 @@ do_test (void) + if (wmemcmp (wbuf, L"aabcdefghi", 10)) + 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)) + FAIL (); + +@@ -584,7 +601,8 @@ do_test (void) + if (wmemcmp (wbuf, L"aabcdefghi", 10)) + 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)) + FAIL (); + +@@ -626,7 +644,8 @@ do_test (void) + if (wmemcmp (wa.buf1, L"aabcdefghi", 10)) + 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)) + FAIL (); + +@@ -695,6 +714,7 @@ do_test (void) + wmemmove (wbuf + 2, wbuf + 1, l0 + 9); + CHK_FAIL_END + ++#ifdef _GNU_SOURCE + CHK_FAIL_START + wp = wmempcpy (wbuf + 6, L"abcde", 5); + CHK_FAIL_END +@@ -702,6 +722,7 @@ do_test (void) + CHK_FAIL_START + wp = wmempcpy (wbuf + 6, L"abcde", l0 + 5); + CHK_FAIL_END ++#endif + + CHK_FAIL_START + wmemset (wbuf + 9, L'j', 2); +@@ -769,6 +790,7 @@ do_test (void) + wmemmove (wa.buf1 + 2, wa.buf1 + 1, l0 + 9); + CHK_FAIL_END + ++#ifdef _GNU_SOURCE + CHK_FAIL_START + wp = wmempcpy (wa.buf1 + 6, L"abcde", 5); + CHK_FAIL_END +@@ -776,6 +798,7 @@ do_test (void) + CHK_FAIL_START + wp = wmempcpy (wa.buf1 + 6, L"abcde", l0 + 5); + CHK_FAIL_END ++#endif + + CHK_FAIL_START + wmemset (wa.buf1 + 9, L'j', 2); +@@ -907,6 +930,7 @@ do_test (void) + if (fprintf (fp, buf2 + 4, str5) != 7) + FAIL (); + ++#ifdef _GNU_SOURCE + char *my_ptr = NULL; + strcpy (buf2 + 2, "%n%s%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) + FAIL (); + obstack_free (&obs, NULL); ++#endif + + if (freopen (temp_filename, "r", stdin) == NULL) + { +@@ -983,6 +1008,7 @@ do_test (void) + + rewind (stdin); + ++#ifdef _GNU_SOURCE + if (fgets_unlocked (buf, buf_size, stdin) != buf + || memcmp (buf, "abcdefgh\n", 10)) + FAIL (); +@@ -1009,6 +1035,7 @@ do_test (void) + #endif + + rewind (stdin); ++#endif + + if (fread (buf, 1, buf_size, stdin) != buf_size + || memcmp (buf, "abcdefgh\nA", 10)) +@@ -1579,7 +1606,10 @@ do_test (void) + ret = 1; + } + +- int fd = posix_openpt (O_RDWR); ++ int fd; ++ ++#ifdef _GNU_SOURCE ++ fd = posix_openpt (O_RDWR); + if (fd != -1) + { + char enough[1000]; +@@ -1595,6 +1625,7 @@ do_test (void) + #endif + close (fd); + } ++#endif + + #if PATH_MAX > 0 + confstr (_CS_GNU_LIBC_VERSION, largebuf, sizeof (largebuf)); +@@ -1712,8 +1743,9 @@ do_test (void) + poll (fds, l0 + 2, 0); + CHK_FAIL_END + #endif ++#ifdef _GNU_SOURCE + ppoll (fds, 1, NULL, NULL); +-#if __USE_FORTIFY_LEVEL >= 1 ++# if __USE_FORTIFY_LEVEL >= 1 + CHK_FAIL_START + ppoll (fds, 2, NULL, NULL); + CHK_FAIL_END +@@ -1721,6 +1753,7 @@ do_test (void) + CHK_FAIL_START + ppoll (fds, l0 + 2, NULL, NULL); + CHK_FAIL_END ++# endif + #endif + + return ret; +diff --git a/posix/bits/unistd.h b/posix/bits/unistd.h +index a456d1723547db70..ddfaed4dd7574cd2 100644 +--- a/posix/bits/unistd.h ++++ b/posix/bits/unistd.h +@@ -38,7 +38,7 @@ read (int __fd, void *__buf, size_t __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, + __off_t __offset, size_t __bufsize) __wur; + extern ssize_t __pread64_chk (int __fd, void *__buf, size_t __nbytes, +diff --git a/string/bits/string_fortified.h b/string/bits/string_fortified.h +index 27ec273ec41cd81c..3f86629bf8fc51a2 100644 +--- a/string/bits/string_fortified.h ++++ b/string/bits/string_fortified.h +@@ -94,7 +94,7 @@ __NTH (strcpy (char *__restrict __dest, const char *__restrict __src)) + return __builtin___strcpy_chk (__dest, __src, __glibc_objsize (__dest)); + } + +-#ifdef __USE_GNU ++#ifdef __USE_XOPEN2K8 + __fortify_function char * + __NTH (stpcpy (char *__restrict __dest, const char *__restrict __src)) + { +@@ -111,14 +111,15 @@ __NTH (strncpy (char *__restrict __dest, const char *__restrict __src, + __glibc_objsize (__dest)); + } + +-#if __GNUC_PREREQ (4, 7) || __glibc_clang_prereq (2, 6) ++#ifdef __USE_XOPEN2K8 ++# if __GNUC_PREREQ (4, 7) || __glibc_clang_prereq (2, 6) + __fortify_function char * + __NTH (stpncpy (char *__dest, const char *__src, size_t __n)) + { + return __builtin___stpncpy_chk (__dest, __src, __n, + __glibc_objsize (__dest)); + } +-#else ++# else + extern char *__stpncpy_chk (char *__dest, const char *__src, size_t __n, + size_t __destlen) __THROW; + extern char *__REDIRECT_NTH (__stpncpy_alias, (char *__dest, const char *__src, +@@ -132,6 +133,7 @@ __NTH (stpncpy (char *__dest, const char *__src, size_t __n)) + return __stpncpy_chk (__dest, __src, __n, __bos (__dest)); + return __stpncpy_alias (__dest, __src, __n); + } ++# endif + #endif + + +diff --git a/support/xsignal.h b/support/xsignal.h +index 9ab8d1bfddf6c598..fae6108a522ae5fe 100644 +--- a/support/xsignal.h ++++ b/support/xsignal.h +@@ -28,7 +28,9 @@ __BEGIN_DECLS + terminate the process on error. */ + + void xraise (int sig); ++#ifdef _GNU_SOURCE + sighandler_t xsignal (int sig, sighandler_t handler); ++#endif + void xsigaction (int sig, const struct sigaction *newact, + struct sigaction *oldact); + +diff --git a/wcsmbs/bits/wchar2.h b/wcsmbs/bits/wchar2.h +index f82bba481981e4fb..5c68979e96a504b4 100644 +--- a/wcsmbs/bits/wchar2.h ++++ b/wcsmbs/bits/wchar2.h +@@ -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, + const char **__restrict __src, size_t __nmc, + size_t __len, mbstate_t *__restrict __ps, diff --git a/SOURCES/glibc-rh2063712.patch b/SOURCES/glibc-rh2063712.patch new file mode 100644 index 0000000..b66fce4 --- /dev/null +++ b/SOURCES/glibc-rh2063712.patch @@ -0,0 +1,208 @@ +This is a downstream rework of this upstream patch: + + [PATCH v2 2/2] nss: Protect against errno changes in function lookup (bug 28953) + + +The NSS module loading code has been rewritten upstream, which is why +only the test can be reused. NSS_DECLARE_MODULE_FUNCTIONS does not yet +exist downstream, so this part had to be skipped. + +diff --git a/nss/Makefile b/nss/Makefile +index d5c28a6b5ed3661c..e8a7d9c7b3cefcdf 100644 +--- a/nss/Makefile ++++ b/nss/Makefile +@@ -59,7 +59,8 @@ tests = test-netdb test-digits-dots tst-nss-getpwent bug17079 \ + tst-nss-test2 \ + tst-nss-test3 \ + tst-nss-test4 \ +- tst-nss-test5 ++ tst-nss-test5 \ ++ tst-nss-test_errno + xtests = bug-erange + + tests-container = \ +@@ -130,7 +131,7 @@ routines += $(libnss_files-routines) + static-only-routines += $(libnss_files-routines) + tests-static += tst-nss-static + endif +-extra-test-objs += nss_test1.os nss_test2.os ++extra-test-objs += nss_test1.os nss_test2.os nss_test_errno.os + + include ../Rules + +@@ -166,10 +167,13 @@ rtld-tests-LDFLAGS += -Wl,--dynamic-list=nss_test.ver + + libof-nss_test1 = extramodules + libof-nss_test2 = extramodules ++libof-nss_test_errno = extramodules + $(objpfx)/libnss_test1.so: $(objpfx)nss_test1.os $(link-libc-deps) + $(build-module) + $(objpfx)/libnss_test2.so: $(objpfx)nss_test2.os $(link-libc-deps) + $(build-module) ++$(objpfx)/libnss_test_errno.so: $(objpfx)nss_test_errno.os $(link-libc-deps) ++ $(build-module) + $(objpfx)nss_test2.os : nss_test1.c + ifdef libnss_test1.so-version + $(objpfx)/libnss_test1.so$(libnss_test1.so-version): $(objpfx)/libnss_test1.so +@@ -179,9 +183,13 @@ ifdef libnss_test2.so-version + $(objpfx)/libnss_test2.so$(libnss_test2.so-version): $(objpfx)/libnss_test2.so + $(make-link) + endif ++$(objpfx)/libnss_test_errno.so$(libnss_files.so-version): \ ++ $(objpfx)/libnss_test_errno.so ++ $(make-link) + $(patsubst %,$(objpfx)%.out,$(tests)) : \ + $(objpfx)/libnss_test1.so$(libnss_test1.so-version) \ +- $(objpfx)/libnss_test2.so$(libnss_test2.so-version) ++ $(objpfx)/libnss_test2.so$(libnss_test2.so-version) \ ++ $(objpfx)/libnss_test_errno.so$(libnss_files.so-version) + + ifeq (yes,$(have-thread-library)) + $(objpfx)tst-cancel-getpwuid_r: $(shared-thread-library) +diff --git a/nss/nss_test_errno.c b/nss/nss_test_errno.c +new file mode 100644 +index 0000000000000000..ca75c890aa057869 +--- /dev/null ++++ b/nss/nss_test_errno.c +@@ -0,0 +1,53 @@ ++/* NSS service provider with errno clobber. ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++ ++static void __attribute__ ((constructor)) ++init (void) ++{ ++ /* An arbitrary error code which is otherwise not used. */ ++ errno = ELIBBAD; ++} ++ ++/* Lookup functions for pwd follow that do not return any data. */ ++ ++enum nss_status ++_nss_test_errno_setpwent (int stayopen) ++{ ++ setenv ("_nss_test_errno_setpwent", "yes", 1); ++ return NSS_STATUS_SUCCESS; ++} ++ ++enum nss_status ++_nss_test_errno_getpwent_r (struct passwd *result, ++ char *buffer, size_t size, int *errnop) ++{ ++ setenv ("_nss_test_errno_getpwent_r", "yes", 1); ++ return NSS_STATUS_NOTFOUND; ++} ++ ++enum nss_status ++_nss_test_errno_endpwent (void) ++{ ++ setenv ("_nss_test_errno_endpwent", "yes", 1); ++ return NSS_STATUS_SUCCESS; ++} +diff --git a/nss/nsswitch.c b/nss/nsswitch.c +index 17adf1ef03f93d60..e59ab674e0426b26 100644 +--- a/nss/nsswitch.c ++++ b/nss/nsswitch.c +@@ -401,6 +401,7 @@ void * + __nss_lookup_function (service_user *ni, const char *fct_name) + { + void **found, *result; ++ int saved_errno = errno; + + /* We now modify global data. Protect it. */ + __libc_lock_lock (lock); +@@ -523,6 +524,8 @@ __nss_lookup_function (service_user *ni, const char *fct_name) + /* Remove the lock. */ + __libc_lock_unlock (lock); + ++ __set_errno (saved_errno); ++ + return result; + } + libc_hidden_def (__nss_lookup_function) +diff --git a/nss/tst-nss-test_errno.c b/nss/tst-nss-test_errno.c +new file mode 100644 +index 0000000000000000..d2c42dd363a38b0e +--- /dev/null ++++ b/nss/tst-nss-test_errno.c +@@ -0,0 +1,61 @@ ++/* getpwent failure when dlopen clobbers errno (bug 28953). ++ Copyright (C) 2022 Free Software Foundation, Inc. ++ This file is part of the GNU C Library. ++ ++ The GNU C Library is free software; you can redistribute it and/or ++ modify it under the terms of the GNU Lesser General Public ++ License as published by the Free Software Foundation; either ++ version 2.1 of the License, or (at your option) any later version. ++ ++ The GNU C Library is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ Lesser General Public License for more details. ++ ++ You should have received a copy of the GNU Lesser General Public ++ License along with the GNU C Library; if not, see ++ . */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int ++do_test (void) ++{ ++ __nss_configure_lookup ("passwd", "files test_errno"); ++ ++ errno = 0; ++ setpwent (); ++ TEST_COMPARE (errno, 0); ++ ++ bool root_seen = false; ++ while (true) ++ { ++ errno = 0; ++ struct passwd *e = getpwent (); ++ if (e == NULL) ++ break; ++ if (strcmp (e->pw_name, "root")) ++ root_seen = true; ++ } ++ ++ TEST_COMPARE (errno, 0); ++ TEST_VERIFY (root_seen); ++ ++ errno = 0; ++ endpwent (); ++ TEST_COMPARE (errno, 0); ++ ++ TEST_COMPARE_STRING (getenv ("_nss_test_errno_setpwent"), "yes"); ++ TEST_COMPARE_STRING (getenv ("_nss_test_errno_getpwent_r"), "yes"); ++ TEST_COMPARE_STRING (getenv ("_nss_test_errno_endpwent"), "yes"); ++ ++ return 0; ++} ++ ++#include diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec index 446f38d..9a3e247 100644 --- a/SPECS/glibc.spec +++ b/SPECS/glibc.spec @@ -1,6 +1,6 @@ %define glibcsrcdir glibc-2.28 %define glibcversion 2.28 -%define glibcrelease 189%{?dist} +%define glibcrelease 196%{?dist} # Pre-release tarballs are pulled in from git using a command that is # effectively: # @@ -855,6 +855,29 @@ Patch660: glibc-rh2045063-2.patch Patch661: glibc-rh2045063-3.patch Patch662: glibc-rh2045063-4.patch Patch663: glibc-rh2045063-5.patch +Patch664: glibc-rh2054790.patch +Patch665: glibc-rh2037416-1.patch +Patch666: glibc-rh2037416-2.patch +Patch667: glibc-rh2037416-3.patch +Patch668: glibc-rh2037416-4.patch +Patch669: glibc-rh2037416-5.patch +Patch670: glibc-rh2037416-6.patch +Patch671: glibc-rh2037416-7.patch +Patch672: glibc-rh2037416-8.patch +Patch673: glibc-rh2033684-1.patch +Patch674: glibc-rh2033684-2.patch +Patch675: glibc-rh2033684-3.patch +Patch676: glibc-rh2033684-4.patch +Patch677: glibc-rh2033684-5.patch +Patch678: glibc-rh2033684-6.patch +Patch679: glibc-rh2033684-7.patch +Patch680: glibc-rh2033684-8.patch +Patch681: glibc-rh2033684-9.patch +Patch682: glibc-rh2033684-10.patch +Patch683: glibc-rh2033684-11.patch +Patch684: glibc-rh2033684-12.patch +Patch685: glibc-rh2063712.patch +Patch686: glibc-rh2063042.patch ############################################################################## # Continued list of core "glibc" package information: @@ -1746,6 +1769,20 @@ $olddir/build-%{target}/testrun.sh \ # default locale-archive without modification, and leaving compiled # locales as they are (without inclusion into the archive). cp locale-archive{,.tmpl} + +# Almost half the LC_CTYPE files in langpacks are identical to the C.utf8 +# variant which is installed by default. When we keep them as hardlinks, +# each langpack ends up retaining a copy. If we convert these to symbolic +# links instead, we save ~350K each when they get installed that way. +# +# LC_MEASUREMENT and LC_PAPER also have several duplicates but we don't +# bother with these because they are only ~30 bytes each. +pushd %{glibc_sysroot}/usr/lib/locale +for f in $(find eo *_* -samefile C.utf8/LC_CTYPE); do + rm $f && ln -s '../C.utf8/LC_CTYPE' $f +done +popd + # Create the file lists for the language specific sub-packages: for i in eo *_* do @@ -2054,7 +2091,7 @@ chmod 0444 master.filelist # - All the libnss files (we add back the ones we want later). # - All bench test binaries. # - The aux-cache, since it's handled specially in the files section. -# - The build-locale-archive binary since it's in the common package. +# - The build-locale-archive binary since it's in the all-langpacks package. # - Extra gconv modules. We add the required modules later. cat master.filelist \ | grep -v \ @@ -2179,13 +2216,15 @@ grep '%{_libdir}/lib.*\.a' < master.filelist \ ############################################################################### # All of the bin and certain sbin files go into the common package except -# iconvconfig which needs to go in glibc. Likewise nscd is excluded because +# iconvconfig which needs to go in glibc, and build-locale-archive which +# needs to go into glibc-all-langpacks. Likewise nscd is excluded because # it goes in nscd. The iconvconfig binary is kept in the main glibc package # because we use it in the post-install scriptlet to rebuild the # gconv-modules.cache. grep '%{_prefix}/bin' master.filelist >> common.filelist grep '%{_prefix}/sbin' master.filelist \ | grep -v '%{_prefix}/sbin/iconvconfig' \ + | grep -v '%{_prefix}/sbin/build-locale-archive' \ | grep -v 'nscd' >> common.filelist # All of the files under share go into the common package since they should be # multilib-independent. @@ -2201,9 +2240,6 @@ grep '%{_prefix}/share' master.filelist \ -e '%{_docdir}' \ >> common.filelist -# Add the binary to build locales to the common subpackage. -echo '%{_prefix}/sbin/build-locale-archive' >> common.filelist - ############################################################################### # nscd ############################################################################### @@ -2613,6 +2649,8 @@ fi %files all-langpacks %attr(0644,root,root) %verify(not md5 size mtime) %{_prefix}/lib/locale/locale-archive.tmpl %attr(0644,root,root) %verify(not md5 size mtime mode) %ghost %{_prefix}/lib/locale/locale-archive +# build-locale-archive re-generates locale-archive during install/upgrade/downgrade +%attr(0700,root,root) %{_prefix}/sbin/build-locale-archive %files locale-source %dir %{_prefix}/share/i18n/locales @@ -2670,6 +2708,28 @@ fi %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared %changelog +* Tue Mar 15 2022 Siddhesh Poyarekar 2.28-196 +- Synchronize feature guards in fortified functions (#2063042) + +* Mon Mar 14 2022 Florian Weimer - 2.28-195 +- nss: Avoid clobbering errno in get*ent via dlopen (#2063712) + +* Fri Mar 11 2022 Siddhesh Poyarekar 2.28-194 +- Enable support for _FORTIFY_SOURCE=3 for gcc 12 and later (#2033684) + +* Wed Mar 9 2022 DJ Delorie - 2.28-193 +- memory operation A64FX SVE performance improvement (#2037416) + +* Mon Mar 07 2022 Arjun Shankar - 2.28-192 +- Move build-locale-archive to glibc-all-langpacks (#2057513) + +* Mon Mar 07 2022 Arjun Shankar - 2.28-191 +- Fix build-locale-archive to handle symbolic links (#2054790) + +* Fri Mar 04 2022 Arjun Shankar - 2.28-190 +- Reduce installed size of some langpacks by de-duplicating LC_CTYPE (#2054790) +- Fix localedef so it can handle symbolic links when generating locale-archive. + * Thu Jan 27 2022 Siddhesh Poyarekar - 2.28-189 - CVE-2021-3999: getcwd: align stack on clone in aarch64 and fix a memory leak (#2032281)