diff --git a/gating.yaml b/gating.yaml new file mode 100644 index 0000000..ac6d3d8 --- /dev/null +++ b/gating.yaml @@ -0,0 +1,13 @@ +--- !Policy +product_versions: + - fedora-* +decision_context: bodhi_update_push_stable +subject_type: koji_build +rules: + - !PassingTestCaseRule {test_case_name: baseos-qe.koji-build.scratch-build.validation} +--- !Policy +product_versions: + - rhel-9 +decision_context: osci_compose_gate +rules: + - !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.tier1.functional} diff --git a/glibc-upstream-2.33-10.patch b/glibc-upstream-2.33-10.patch new file mode 100644 index 0000000..deb97fe --- /dev/null +++ b/glibc-upstream-2.33-10.patch @@ -0,0 +1,165 @@ +commit 3e880d733753183696d1a81c34caef3a9add2b0c +Author: DJ Delorie +Date: Thu Feb 18 15:26:30 2021 -0500 + + nss: Re-enable NSS module loading after chroot [BZ #27389] + + The glibc 2.33 release enabled /etc/nsswitch.conf reloading, + and to prevent potential security issues like CVE-2019-14271 + the re-loading of nsswitch.conf and all mdoules was disabled + when the root filesystem changes (see bug 27077). + + Unfortunately php-lpfm and openldap both require the ability + to continue to load NSS modules after chroot. The packages + do not exec after the chroot, and so do not cause the + protections to be reset. The only solution is to re-enable + only NSS module loading (not nsswitch.conf reloading) and so + get back the previous glibc behaviour. + + In the future we may introduce a way to harden applications + so they do not reload NSS modules once the root filesystem + changes, or that only files/dns are available pre-loaded + (or builtin). + + Reviewed-by: Carlos O'Donell + (cherry picked from commit 58673149f37389495c098421085ffdb468b3f7ad) + +diff --git a/nss/nss_database.c b/nss/nss_database.c +index e1bef6bd75ce0160..fb72d0cc03d5c0c8 100644 +--- a/nss/nss_database.c ++++ b/nss/nss_database.c +@@ -402,7 +402,6 @@ nss_database_check_reload_and_get (struct nss_database_state *local, + atomic_store_release (&local->data.reload_disabled, 1); + *result = local->data.services[database_index]; + __libc_lock_unlock (local->lock); +- __nss_module_disable_loading (); + return true; + } + local->root_ino = str.st_ino; +diff --git a/nss/tst-reload2.c b/nss/tst-reload2.c +index 5dae16b4f05096e8..5ecb032e9fcd6868 100644 +--- a/nss/tst-reload2.c ++++ b/nss/tst-reload2.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -48,7 +49,7 @@ static const char *group_4[] = { + "alpha", "beta", "gamma", "fred", NULL + }; + +-static struct group group_table_data[] = ++static struct group group_table_data1[] = + { + GRP (4), + GRP_LAST () +@@ -58,7 +59,7 @@ void + _nss_test1_init_hook (test_tables *t) + { + t->pwd_table = pwd_table1; +- t->grp_table = group_table_data; ++ t->grp_table = group_table_data1; + } + + static struct passwd pwd_table2[] = +@@ -68,10 +69,21 @@ static struct passwd pwd_table2[] = + PWD_LAST () + }; + ++static const char *group_5[] = { ++ "fred", NULL ++}; ++ ++static struct group group_table_data2[] = ++ { ++ GRP (5), ++ GRP_LAST () ++ }; ++ + void + _nss_test2_init_hook (test_tables *t) + { + t->pwd_table = pwd_table2; ++ t->grp_table = group_table_data2; + } + + static int +@@ -79,6 +91,7 @@ do_test (void) + { + struct passwd *pw; + struct group *gr; ++ struct hostent *he; + char buf1[PATH_MAX]; + char buf2[PATH_MAX]; + +@@ -99,7 +112,9 @@ do_test (void) + TEST_COMPARE (pw->pw_uid, 1234); + + /* This just loads the test2 DSO. */ +- gr = getgrnam ("name4"); ++ gr = getgrgid (5); ++ TEST_VERIFY (gr != NULL); ++ + + /* Change the root dir. */ + +@@ -114,15 +129,21 @@ do_test (void) + if (pw) + TEST_VERIFY (pw->pw_uid != 2468); + +- /* The "files" DSO should not be loaded. */ +- gr = getgrnam ("test3"); +- TEST_VERIFY (gr == NULL); +- + /* We should still be using the old configuration. */ + pw = getpwnam ("test1"); + TEST_VERIFY (pw != NULL); + if (pw) + TEST_COMPARE (pw->pw_uid, 1234); ++ gr = getgrgid (5); ++ TEST_VERIFY (gr != NULL); ++ gr = getgrnam ("name4"); ++ TEST_VERIFY (gr == NULL); ++ ++ /* hosts in the outer nsswitch is files; the inner one is test1. ++ Verify that we're still using the outer nsswitch *and* that we ++ can load the files DSO. */ ++ he = gethostbyname ("test2"); ++ TEST_VERIFY (he != NULL); + + return 0; + } +diff --git a/nss/tst-reload2.root/etc/hosts b/nss/tst-reload2.root/etc/hosts +new file mode 100644 +index 0000000000000000..bbd9e494ef39acc8 +--- /dev/null ++++ b/nss/tst-reload2.root/etc/hosts +@@ -0,0 +1 @@ ++1.2.3.4 test1 +diff --git a/nss/tst-reload2.root/etc/nsswitch.conf b/nss/tst-reload2.root/etc/nsswitch.conf +index 570795ae22d116f1..688a5895191a913b 100644 +--- a/nss/tst-reload2.root/etc/nsswitch.conf ++++ b/nss/tst-reload2.root/etc/nsswitch.conf +@@ -1,2 +1,3 @@ + passwd: test1 + group: test2 ++hosts: files +diff --git a/nss/tst-reload2.root/subdir/etc/hosts b/nss/tst-reload2.root/subdir/etc/hosts +new file mode 100644 +index 0000000000000000..0a2cbd4337f80bc3 +--- /dev/null ++++ b/nss/tst-reload2.root/subdir/etc/hosts +@@ -0,0 +1 @@ ++1.2.3.4 test2 +diff --git a/nss/tst-reload2.root/subdir/etc/nsswitch.conf b/nss/tst-reload2.root/subdir/etc/nsswitch.conf +index f1d73f8765116d1d..fea271869ef98458 100644 +--- a/nss/tst-reload2.root/subdir/etc/nsswitch.conf ++++ b/nss/tst-reload2.root/subdir/etc/nsswitch.conf +@@ -1,2 +1,3 @@ + passwd: test2 + group: files ++hosts: test1 diff --git a/glibc-upstream-2.33-7.patch b/glibc-upstream-2.33-7.patch new file mode 100644 index 0000000..990c6eb --- /dev/null +++ b/glibc-upstream-2.33-7.patch @@ -0,0 +1,580 @@ +commit 33dc1dd602aecadf2fc5f322715e6f453dda40b5 +Author: Florian Weimer +Date: Tue Mar 2 15:46:42 2021 +0100 + + ld.so: Implement the --list-diagnostics option + + (cherry picked from commit 851f32cf7bf7067f73b991610778915edd57d7b4) + +diff --git a/elf/Makefile b/elf/Makefile +index 5d666b1b0c7ba82c..7610fa080f3f4738 100644 +--- a/elf/Makefile ++++ b/elf/Makefile +@@ -66,7 +66,7 @@ elide-routines.os = $(all-dl-routines) dl-support enbl-secure dl-origin \ + # interpreter and operating independent of libc. + rtld-routines = rtld $(all-dl-routines) dl-sysdep dl-environ dl-minimal \ + dl-error-minimal dl-conflict dl-hwcaps dl-hwcaps_split dl-hwcaps-subdirs \ +- dl-usage ++ dl-usage dl-diagnostics dl-diagnostics-kernel dl-diagnostics-cpu + all-rtld-routines = $(rtld-routines) $(sysdep-rtld-routines) + + CFLAGS-dl-runtime.c += -fexceptions -fasynchronous-unwind-tables +@@ -678,6 +678,9 @@ CFLAGS-cache.c += $(SYSCONF-FLAGS) + CFLAGS-rtld.c += $(SYSCONF-FLAGS) + CFLAGS-dl-usage.c += $(SYSCONF-FLAGS) \ + -D'RTLD="$(rtlddir)/$(rtld-installed-name)"' ++CFLAGS-dl-diagnostics.c += $(SYSCONF-FLAGS) \ ++ -D'PREFIX="$(prefix)"' \ ++ -D'RTLD="$(rtlddir)/$(rtld-installed-name)"' + + cpp-srcs-left := $(all-rtld-routines:=.os) + lib := rtld +diff --git a/elf/dl-diagnostics-cpu.c b/elf/dl-diagnostics-cpu.c +new file mode 100644 +index 0000000000000000..f7d149764bcb35a1 +--- /dev/null ++++ b/elf/dl-diagnostics-cpu.c +@@ -0,0 +1,24 @@ ++/* Print CPU diagnostics data in ld.so. Stub version. ++ Copyright (C) 2021 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 ++ ++void ++_dl_diagnostics_cpu (void) ++{ ++} +diff --git a/elf/dl-diagnostics-kernel.c b/elf/dl-diagnostics-kernel.c +new file mode 100644 +index 0000000000000000..831c358f1463cbf4 +--- /dev/null ++++ b/elf/dl-diagnostics-kernel.c +@@ -0,0 +1,24 @@ ++/* Print kernel diagnostics data in ld.so. Stub version. ++ Copyright (C) 2021 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 ++ ++void ++_dl_diagnostics_kernel (void) ++{ ++} +diff --git a/elf/dl-diagnostics.c b/elf/dl-diagnostics.c +new file mode 100644 +index 0000000000000000..bef224b36cbf5fc3 +--- /dev/null ++++ b/elf/dl-diagnostics.c +@@ -0,0 +1,265 @@ ++/* Print diagnostics data in ld.so. ++ Copyright (C) 2021 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 ++#include ++#include ++#include ++#include "trusted-dirs.h" ++#include "version.h" ++ ++/* Write CH to standard output. */ ++static void ++_dl_putc (char ch) ++{ ++ _dl_write (STDOUT_FILENO, &ch, 1); ++} ++ ++/* Print CH to standard output, quoting it if necessary. */ ++static void ++print_quoted_char (char ch) ++{ ++ if (ch < ' ' || ch > '~') ++ { ++ char buf[4]; ++ buf[0] = '\\'; ++ buf[1] = '0' + ((ch >> 6) & 7); ++ buf[2] = '0' + ((ch >> 6) & 7); ++ buf[3] = '0' + (ch & 7); ++ _dl_write (STDOUT_FILENO, buf, 4); ++ } ++ else ++ { ++ if (ch == '\\' || ch == '"') ++ _dl_putc ('\\'); ++ _dl_putc (ch); ++ } ++} ++ ++/* Print S of LEN bytes to standard output, quoting characters as ++ needed. */ ++static void ++print_string_length (const char *s, size_t len) ++{ ++ _dl_putc ('"'); ++ for (size_t i = 0; i < len; ++i) ++ print_quoted_char (s[i]); ++ _dl_putc ('"'); ++} ++ ++void ++_dl_diagnostics_print_string (const char *s) ++{ ++ if (s == NULL) ++ { ++ _dl_printf ("0x0"); ++ return; ++ } ++ ++ _dl_putc ('"'); ++ while (*s != '\0') ++ { ++ print_quoted_char (*s); ++ ++s; ++ } ++ _dl_putc ('"'); ++} ++ ++void ++_dl_diagnostics_print_labeled_string (const char *label, const char *s) ++{ ++ _dl_printf ("%s=", label); ++ _dl_diagnostics_print_string (s); ++ _dl_putc ('\n'); ++} ++ ++void ++_dl_diagnostics_print_labeled_value (const char *label, uint64_t value) ++{ ++ if (sizeof (value) == sizeof (unsigned long int)) ++ /* _dl_printf can print 64-bit values directly. */ ++ _dl_printf ("%s=0x%lx\n", label, (unsigned long int) value); ++ else ++ { ++ uint32_t high = value >> 32; ++ uint32_t low = value; ++ if (high == 0) ++ _dl_printf ("%s=0x%x\n", label, low); ++ else ++ _dl_printf ("%s=0x%x%08x\n", label, high, low); ++ } ++} ++ ++/* Return true if ENV is an unfiltered environment variable. */ ++static bool ++unfiltered_envvar (const char *env, size_t *name_length) ++{ ++ char *env_equal = strchr (env, '='); ++ if (env_equal == NULL) ++ { ++ /* Always dump malformed entries. */ ++ *name_length = strlen (env); ++ return true; ++ } ++ size_t envname_length = env_equal - env; ++ *name_length = envname_length; ++ ++ /* LC_ and LD_ variables. */ ++ if (env[0] == 'L' && (env[1] == 'C' || env[1] == 'D') ++ && env[2] == '_') ++ return true; ++ ++ /* MALLOC_ variables. */ ++ if (strncmp (env, "MALLOC_", strlen ("MALLOC_")) == 0) ++ return true; ++ ++ static const char unfiltered[] = ++ "DATEMSK\0" ++ "GCONV_PATH\0" ++ "GETCONF_DIR\0" ++ "GETCONF_DIR\0" ++ "GLIBC_TUNABLES\0" ++ "GMON_OUTPUT_PREFIX\0" ++ "HESIOD_CONFIG\0" ++ "HES_DOMAIN\0" ++ "HOSTALIASES\0" ++ "I18NPATH\0" ++ "IFS\0" ++ "LANG\0" ++ "LOCALDOMAIN\0" ++ "LOCPATH\0" ++ "MSGVERB\0" ++ "NIS_DEFAULTS\0" ++ "NIS_GROUP\0" ++ "NIS_PATH\0" ++ "NLSPATH\0" ++ "PATH\0" ++ "POSIXLY_CORRECT\0" ++ "RESOLV_HOST_CONF\0" ++ "RES_OPTIONS\0" ++ "SEV_LEVEL\0" ++ "TMPDIR\0" ++ "TZ\0" ++ "TZDIR\0" ++ /* Two null bytes at the end to mark the end of the list via an ++ empty substring. */ ++ ; ++ for (const char *candidate = unfiltered; *candidate != '\0'; ) ++ { ++ size_t candidate_length = strlen (candidate); ++ if (candidate_length == envname_length ++ && memcmp (candidate, env, candidate_length) == 0) ++ return true; ++ candidate += candidate_length + 1; ++ } ++ ++ return false; ++} ++ ++/* Dump the process environment. */ ++static void ++print_environ (char **environ) ++{ ++ unsigned int index = 0; ++ for (char **envp = environ; *envp != NULL; ++envp) ++ { ++ char *env = *envp; ++ size_t name_length; ++ bool unfiltered = unfiltered_envvar (env, &name_length); ++ _dl_printf ("env%s[0x%x]=", ++ unfiltered ? "" : "_filtered", index); ++ if (unfiltered) ++ _dl_diagnostics_print_string (env); ++ else ++ print_string_length (env, name_length); ++ _dl_putc ('\n'); ++ ++index; ++ } ++} ++ ++/* Print configured paths and the built-in search path. */ ++static void ++print_paths (void) ++{ ++ _dl_diagnostics_print_labeled_string ("path.prefix", PREFIX); ++ _dl_diagnostics_print_labeled_string ("path.rtld", RTLD); ++ _dl_diagnostics_print_labeled_string ("path.sysconfdir", SYSCONFDIR); ++ ++ unsigned int index = 0; ++ static const char *system_dirs = SYSTEM_DIRS "\0"; ++ for (const char *e = system_dirs; *e != '\0'; ) ++ { ++ size_t len = strlen (e); ++ _dl_printf ("path.system_dirs[0x%x]=", index); ++ print_string_length (e, len); ++ _dl_putc ('\n'); ++ ++index; ++ e += len + 1; ++ } ++} ++ ++/* Print information about the glibc version. */ ++static void ++print_version (void) ++{ ++ _dl_diagnostics_print_labeled_string ("version.release", RELEASE); ++ _dl_diagnostics_print_labeled_string ("version.version", VERSION); ++} ++ ++void ++_dl_print_diagnostics (char **environ) ++{ ++#ifdef HAVE_DL_DISCOVER_OSVERSION ++ _dl_diagnostics_print_labeled_value ++ ("dl_discover_osversion", _dl_discover_osversion ()); ++#endif ++ _dl_diagnostics_print_labeled_string ("dl_dst_lib", DL_DST_LIB); ++ _dl_diagnostics_print_labeled_value ("dl_hwcap", GLRO (dl_hwcap)); ++ _dl_diagnostics_print_labeled_value ("dl_hwcap_important", HWCAP_IMPORTANT); ++ _dl_diagnostics_print_labeled_value ("dl_hwcap2", GLRO (dl_hwcap2)); ++ _dl_diagnostics_print_labeled_string ++ ("dl_hwcaps_subdirs", _dl_hwcaps_subdirs); ++ _dl_diagnostics_print_labeled_value ++ ("dl_hwcaps_subdirs_active", _dl_hwcaps_subdirs_active ()); ++ _dl_diagnostics_print_labeled_value ("dl_osversion", GLRO (dl_osversion)); ++ _dl_diagnostics_print_labeled_value ("dl_pagesize", GLRO (dl_pagesize)); ++ _dl_diagnostics_print_labeled_string ("dl_platform", GLRO (dl_platform)); ++ _dl_diagnostics_print_labeled_string ++ ("dl_profile_output", GLRO (dl_profile_output)); ++ _dl_diagnostics_print_labeled_value ++ ("dl_string_platform", _dl_string_platform ( GLRO (dl_platform))); ++ ++ _dl_diagnostics_print_labeled_string ("dso.ld", LD_SO); ++ _dl_diagnostics_print_labeled_string ("dso.libc", LIBC_SO); ++ ++ print_environ (environ); ++ print_paths (); ++ print_version (); ++ ++ _dl_diagnostics_kernel (); ++ _dl_diagnostics_cpu (); ++ ++ _exit (EXIT_SUCCESS); ++} +diff --git a/elf/dl-diagnostics.h b/elf/dl-diagnostics.h +new file mode 100644 +index 0000000000000000..27dcb12bca12e5b6 +--- /dev/null ++++ b/elf/dl-diagnostics.h +@@ -0,0 +1,46 @@ ++/* Interfaces for printing diagnostics in ld.so. ++ Copyright (C) 2021 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 ++ . */ ++ ++#ifndef _DL_DIAGNOSTICS_H ++#define _DL_DIAGNOSTICS_H ++ ++#include ++ ++/* Write the null-terminated string to standard output, surrounded in ++ quotation marks. */ ++void _dl_diagnostics_print_string (const char *s) attribute_hidden; ++ ++/* Like _dl_diagnostics_print_string, but add a LABEL= prefix, and a ++ newline character as a suffix. */ ++void _dl_diagnostics_print_labeled_string (const char *label, const char *s) ++ attribute_hidden; ++ ++/* Print LABEL=VALUE to standard output, followed by a newline ++ character. */ ++void _dl_diagnostics_print_labeled_value (const char *label, uint64_t value) ++ attribute_hidden; ++ ++/* Print diagnostics data for the kernel. Called from ++ _dl_print_diagnostics. */ ++void _dl_diagnostics_kernel (void) attribute_hidden; ++ ++/* Print diagnostics data for the CPU(s). Called from ++ _dl_print_diagnostics. */ ++void _dl_diagnostics_cpu (void) attribute_hidden; ++ ++#endif /* _DL_DIAGNOSTICS_H */ +diff --git a/elf/dl-main.h b/elf/dl-main.h +index 3a5e13c73923ad68..d3820e0063143878 100644 +--- a/elf/dl-main.h ++++ b/elf/dl-main.h +@@ -63,7 +63,7 @@ struct audit_list + enum rtld_mode + { + rtld_mode_normal, rtld_mode_list, rtld_mode_verify, rtld_mode_trace, +- rtld_mode_list_tunables, rtld_mode_help, ++ rtld_mode_list_tunables, rtld_mode_list_diagnostics, rtld_mode_help, + }; + + /* Aggregated state information extracted from environment variables +@@ -121,4 +121,7 @@ _Noreturn void _dl_version (void) attribute_hidden; + _Noreturn void _dl_help (const char *argv0, struct dl_main_state *state) + attribute_hidden; + ++/* Print a diagnostics dump. */ ++_Noreturn void _dl_print_diagnostics (char **environ) attribute_hidden; ++ + #endif /* _DL_MAIN */ +diff --git a/elf/dl-usage.c b/elf/dl-usage.c +index 6e26818bd753a09f..5ad3a72559c0fc28 100644 +--- a/elf/dl-usage.c ++++ b/elf/dl-usage.c +@@ -261,6 +261,7 @@ setting environment variables (which would be inherited by subprocesses).\n\ + --list-tunables list all tunables with minimum and maximum values\n" + #endif + "\ ++ --list-diagnostics list diagnostics information\n\ + --help display this help and exit\n\ + --version output version information and exit\n\ + \n\ +diff --git a/elf/rtld.c b/elf/rtld.c +index 596b6ac3d99d7d8e..94a00e204907bff7 100644 +--- a/elf/rtld.c ++++ b/elf/rtld.c +@@ -141,6 +141,7 @@ static void dl_main_state_init (struct dl_main_state *state); + /* Process all environments variables the dynamic linker must recognize. + Since all of them start with `LD_' we are a bit smarter while finding + all the entries. */ ++extern char **_environ attribute_hidden; + static void process_envvars (struct dl_main_state *state); + + #ifdef DL_ARGV_NOT_RELRO +@@ -1287,6 +1288,14 @@ dl_main (const ElfW(Phdr) *phdr, + ++_dl_argv; + } + #endif ++ else if (! strcmp (_dl_argv[1], "--list-diagnostics")) ++ { ++ state.mode = rtld_mode_list_diagnostics; ++ ++ ++_dl_skip_args; ++ --_dl_argc; ++ ++_dl_argv; ++ } + else if (strcmp (_dl_argv[1], "--help") == 0) + { + state.mode = rtld_mode_help; +@@ -1315,6 +1324,9 @@ dl_main (const ElfW(Phdr) *phdr, + } + #endif + ++ if (state.mode == rtld_mode_list_diagnostics) ++ _dl_print_diagnostics (_environ); ++ + /* If we have no further argument the program was called incorrectly. + Grant the user some education. */ + if (_dl_argc < 2) +@@ -2649,12 +2661,6 @@ a filename can be specified using the LD_DEBUG_OUTPUT environment variable.\n"); + } + } + +-/* Process all environments variables the dynamic linker must recognize. +- Since all of them start with `LD_' we are a bit smarter while finding +- all the entries. */ +-extern char **_environ attribute_hidden; +- +- + static void + process_envvars (struct dl_main_state *state) + { +diff --git a/sysdeps/unix/sysv/linux/dl-diagnostics-kernel.c b/sysdeps/unix/sysv/linux/dl-diagnostics-kernel.c +new file mode 100644 +index 0000000000000000..59f6402c547ba590 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/dl-diagnostics-kernel.c +@@ -0,0 +1,77 @@ ++/* Print kernel diagnostics data in ld.so. Linux version. ++ Copyright (C) 2021 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 ++ ++/* Dump the auxiliary vector to standard output. */ ++static void ++print_auxv (void) ++{ ++ /* See _dl_show_auxv. The code below follows the general output ++ format for diagnostic dumps. */ ++ unsigned int index = 0; ++ for (ElfW(auxv_t) *av = GLRO(dl_auxv); av->a_type != AT_NULL; ++av) ++ { ++ _dl_printf ("auxv[0x%x].a_type=0x%lx\n" ++ "auxv[0x%x].a_val=", ++ index, (unsigned long int) av->a_type, index); ++ if (av->a_type == AT_EXECFN ++ || av->a_type == AT_PLATFORM ++ || av->a_type == AT_BASE_PLATFORM) ++ /* The address of the strings is not useful at all, so print ++ the strings themselvs. */ ++ _dl_diagnostics_print_string ((const char *) av->a_un.a_val); ++ else ++ _dl_printf ("0x%lx", (unsigned long int) av->a_un.a_val); ++ _dl_printf ("\n"); ++ ++index; ++ } ++} ++ ++/* Print one uname entry. */ ++static void ++print_utsname_entry (const char *field, const char *value) ++{ ++ _dl_printf ("uname."); ++ _dl_diagnostics_print_labeled_string (field, value); ++} ++ ++/* Print information from uname, including the kernel version. */ ++static void ++print_uname (void) ++{ ++ struct utsname uts; ++ if (__uname (&uts) == 0) ++ { ++ print_utsname_entry ("sysname", uts.sysname); ++ print_utsname_entry ("nodename", uts.nodename); ++ print_utsname_entry ("release", uts.release); ++ print_utsname_entry ("version", uts.version); ++ print_utsname_entry ("machine", uts.machine); ++ print_utsname_entry ("domainname", uts.domainname); ++ } ++} ++ ++void ++_dl_diagnostics_kernel (void) ++{ ++ print_auxv (); ++ print_uname (); ++} diff --git a/glibc-upstream-2.33-8.patch b/glibc-upstream-2.33-8.patch new file mode 100644 index 0000000..51054cb --- /dev/null +++ b/glibc-upstream-2.33-8.patch @@ -0,0 +1,113 @@ +commit a1eb3915e781c5b9aed89931cbd536a186c15ed5 +Author: Florian Weimer +Date: Tue Mar 2 14:58:05 2021 +0100 + + x86: Automate generation of PREFERRED_FEATURE_INDEX_1 bitfield + + Use a .def file to define the bitfield layout, so that it is possible + to iterate over field members using the preprocessor. + + (cherry picked from commit e4933c8a92ea08eecdf3ab45e7f76c95dc3d20ac) + +diff --git a/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def b/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def +new file mode 100644 +index 0000000000000000..06af1a8dd5c6c2b4 +--- /dev/null ++++ b/sysdeps/x86/include/cpu-features-preferred_feature_index_1.def +@@ -0,0 +1,34 @@ ++/* Bits in the PREFERRED_FEATURE_INDEX_1 bitfield of . ++ Copyright (C) 2020-2021 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 ++ . */ ++ ++BIT (Fast_Rep_String) ++BIT (Fast_Copy_Backward) ++BIT (Slow_BSF) ++BIT (Fast_Unaligned_Load) ++BIT (Prefer_PMINUB_for_stringop) ++BIT (Fast_Unaligned_Copy) ++BIT (I586) ++BIT (I686) ++BIT (Slow_SSE4_2) ++BIT (AVX_Fast_Unaligned_Load) ++BIT (Prefer_MAP_32BIT_EXEC) ++BIT (Prefer_No_VZEROUPPER) ++BIT (Prefer_ERMS) ++BIT (Prefer_No_AVX512) ++BIT (MathVec_Prefer_No_AVX512) ++BIT (Prefer_FSRM) +diff --git a/sysdeps/x86/include/cpu-features.h b/sysdeps/x86/include/cpu-features.h +index 624736b40ebb2cd6..e7f314657c8162da 100644 +--- a/sysdeps/x86/include/cpu-features.h ++++ b/sysdeps/x86/include/cpu-features.h +@@ -757,40 +757,23 @@ enum + #define reg_AESKLE ebx + #define reg_WIDE_KL ebx + +-/* PREFERRED_FEATURE_INDEX_1. */ +-#define bit_arch_I586 (1u << 0) +-#define bit_arch_I686 (1u << 1) +-#define bit_arch_Fast_Rep_String (1u << 2) +-#define bit_arch_Fast_Copy_Backward (1u << 3) +-#define bit_arch_Fast_Unaligned_Load (1u << 4) +-#define bit_arch_Fast_Unaligned_Copy (1u << 5) +-#define bit_arch_Slow_BSF (1u << 6) +-#define bit_arch_Slow_SSE4_2 (1u << 7) +-#define bit_arch_AVX_Fast_Unaligned_Load (1u << 8) +-#define bit_arch_Prefer_MAP_32BIT_EXEC (1u << 9) +-#define bit_arch_Prefer_PMINUB_for_stringop (1u << 10) +-#define bit_arch_Prefer_No_VZEROUPPER (1u << 11) +-#define bit_arch_Prefer_ERMS (1u << 12) +-#define bit_arch_Prefer_FSRM (1u << 13) +-#define bit_arch_Prefer_No_AVX512 (1u << 14) +-#define bit_arch_MathVec_Prefer_No_AVX512 (1u << 15) +- +-#define index_arch_Fast_Rep_String PREFERRED_FEATURE_INDEX_1 +-#define index_arch_Fast_Copy_Backward PREFERRED_FEATURE_INDEX_1 +-#define index_arch_Slow_BSF PREFERRED_FEATURE_INDEX_1 +-#define index_arch_Fast_Unaligned_Load PREFERRED_FEATURE_INDEX_1 +-#define index_arch_Prefer_PMINUB_for_stringop PREFERRED_FEATURE_INDEX_1 +-#define index_arch_Fast_Unaligned_Copy PREFERRED_FEATURE_INDEX_1 +-#define index_arch_I586 PREFERRED_FEATURE_INDEX_1 +-#define index_arch_I686 PREFERRED_FEATURE_INDEX_1 +-#define index_arch_Slow_SSE4_2 PREFERRED_FEATURE_INDEX_1 +-#define index_arch_AVX_Fast_Unaligned_Load PREFERRED_FEATURE_INDEX_1 +-#define index_arch_Prefer_MAP_32BIT_EXEC PREFERRED_FEATURE_INDEX_1 +-#define index_arch_Prefer_No_VZEROUPPER PREFERRED_FEATURE_INDEX_1 +-#define index_arch_Prefer_ERMS PREFERRED_FEATURE_INDEX_1 +-#define index_arch_Prefer_No_AVX512 PREFERRED_FEATURE_INDEX_1 +-#define index_arch_MathVec_Prefer_No_AVX512 PREFERRED_FEATURE_INDEX_1 +-#define index_arch_Prefer_FSRM PREFERRED_FEATURE_INDEX_1 ++/* PREFERRED_FEATURE_INDEX_1. First define the bitindex values ++ sequentially, then define the bit_arch* and index_arch_* lookup ++ constants. */ ++enum ++ { ++#define BIT(x) _bitindex_arch_##x , ++#include "cpu-features-preferred_feature_index_1.def" ++#undef BIT ++ }; ++enum ++ { ++#define BIT(x) \ ++ bit_arch_##x = 1u << _bitindex_arch_##x , \ ++ index_arch_##x = PREFERRED_FEATURE_INDEX_1, ++#include "cpu-features-preferred_feature_index_1.def" ++#undef BIT ++ }; + + /* XCR0 Feature flags. */ + #define bit_XMM_state (1u << 1) diff --git a/glibc-upstream-2.33-9.patch b/glibc-upstream-2.33-9.patch new file mode 100644 index 0000000..73fa1d3 --- /dev/null +++ b/glibc-upstream-2.33-9.patch @@ -0,0 +1,146 @@ +commit 71b2463f6178a6097532dcfe8948bffbe2376dfb +Author: Florian Weimer +Date: Wed Feb 24 13:12:04 2021 +0100 + + x86: Add CPU-specific diagnostics to ld.so --list-diagnostics + + (cherry picked from commit 01a5746b6c8a44dc29d33e056b63485075a6a3cc) + + Adjusted to not print the rep_movsb_stop_threshold field, which + does not exist in glibc 2.33. + +diff --git a/sysdeps/x86/dl-diagnostics-cpu.c b/sysdeps/x86/dl-diagnostics-cpu.c +new file mode 100644 +index 0000000000000000..55c6f35c7cabb4da +--- /dev/null ++++ b/sysdeps/x86/dl-diagnostics-cpu.c +@@ -0,0 +1,116 @@ ++/* Print CPU diagnostics data in ld.so. x86 version. ++ Copyright (C) 2021 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 ++ ++static void ++print_cpu_features_value (const char *label, uint64_t value) ++{ ++ _dl_printf ("x86.cpu_features."); ++ _dl_diagnostics_print_labeled_value (label, value); ++} ++ ++static void ++print_cpu_feature_internal (unsigned int index, const char *kind, ++ unsigned int reg, uint32_t value) ++{ ++ _dl_printf ("x86.cpu_features.features[0x%x].%s[0x%x]=0x%x\n", ++ index, kind, reg, value); ++} ++ ++static void ++print_cpu_feature_preferred (const char *label, unsigned int flag) ++{ ++ _dl_printf("x86.cpu_features.preferred.%s=0x%x\n", label, flag); ++} ++ ++void ++_dl_diagnostics_cpu (void) ++{ ++ const struct cpu_features *cpu_features = __get_cpu_features (); ++ ++ print_cpu_features_value ("basic.kind", cpu_features->basic.kind); ++ print_cpu_features_value ("basic.max_cpuid", cpu_features->basic.max_cpuid); ++ print_cpu_features_value ("basic.family", cpu_features->basic.family); ++ print_cpu_features_value ("basic.model", cpu_features->basic.model); ++ print_cpu_features_value ("basic.stepping", cpu_features->basic.stepping); ++ ++ for (unsigned int index = 0; index < CPUID_INDEX_MAX; ++index) ++ { ++ /* The index values are part of the ABI via ++ , so translating them to strings is not ++ necessary. */ ++ for (unsigned int reg = 0; reg < 4; ++reg) ++ print_cpu_feature_internal ++ (index, "cpuid", reg, ++ cpu_features->features[index].cpuid_array[reg]); ++ for (unsigned int reg = 0; reg < 4; ++reg) ++ print_cpu_feature_internal ++ (index, "usable", reg, ++ cpu_features->features[index].usable_array[reg]); ++ } ++ ++ /* The preferred indicators are not part of the ABI and need to be ++ translated. */ ++#define BIT(x) \ ++ print_cpu_feature_preferred (#x, CPU_FEATURE_PREFERRED_P (cpu_features, x)); ++#include "cpu-features-preferred_feature_index_1.def" ++#undef BIT ++ ++ print_cpu_features_value ("isa_1", cpu_features->isa_1); ++ print_cpu_features_value ("xsave_state_size", ++ cpu_features->xsave_state_size); ++ print_cpu_features_value ("xsave_state_full_size", ++ cpu_features->xsave_state_full_size); ++ print_cpu_features_value ("data_cache_size", cpu_features->data_cache_size); ++ print_cpu_features_value ("shared_cache_size", ++ cpu_features->shared_cache_size); ++ print_cpu_features_value ("non_temporal_threshold", ++ cpu_features->non_temporal_threshold); ++ print_cpu_features_value ("rep_movsb_threshold", ++ cpu_features->rep_movsb_threshold); ++ print_cpu_features_value ("rep_stosb_threshold", ++ cpu_features->rep_stosb_threshold); ++ print_cpu_features_value ("level1_icache_size", ++ cpu_features->level1_icache_size); ++ print_cpu_features_value ("level1_dcache_size", ++ cpu_features->level1_dcache_size); ++ print_cpu_features_value ("level1_dcache_assoc", ++ cpu_features->level1_dcache_assoc); ++ print_cpu_features_value ("level1_dcache_linesize", ++ cpu_features->level1_dcache_linesize); ++ print_cpu_features_value ("level2_cache_size", ++ cpu_features->level2_cache_size); ++ print_cpu_features_value ("level2_cache_assoc", ++ cpu_features->level2_cache_assoc); ++ print_cpu_features_value ("level2_cache_linesize", ++ cpu_features->level2_cache_linesize); ++ print_cpu_features_value ("level3_cache_size", ++ cpu_features->level3_cache_size); ++ print_cpu_features_value ("level3_cache_assoc", ++ cpu_features->level3_cache_assoc); ++ print_cpu_features_value ("level3_cache_linesize", ++ cpu_features->level3_cache_linesize); ++ print_cpu_features_value ("level4_cache_size", ++ cpu_features->level4_cache_size); ++ _Static_assert (offsetof (struct cpu_features, level4_cache_size) ++ + sizeof (cpu_features->level4_cache_size) ++ == sizeof (*cpu_features), ++ "last cpu_features field has been printed"); ++} +diff --git a/sysdeps/x86/include/cpu-features.h b/sysdeps/x86/include/cpu-features.h +index e7f314657c8162da..184dc93c699d9b91 100644 +--- a/sysdeps/x86/include/cpu-features.h ++++ b/sysdeps/x86/include/cpu-features.h +@@ -824,6 +824,8 @@ struct cpuid_feature_internal + }; + }; + ++/* NB: When adding new fields, update sysdeps/x86/dl-diagnostics-cpu.c ++ to print them. */ + struct cpu_features + { + struct cpu_features_basic basic; diff --git a/glibc.spec b/glibc.spec index 8fb3d7e..03f9aad 100644 --- a/glibc.spec +++ b/glibc.spec @@ -96,7 +96,7 @@ Summary: The GNU libc libraries Name: glibc Version: %{glibcversion} -Release: 2%{?dist} +Release: 4%{?dist} # In general, GPLv2+ is used by programs, LGPLv2+ is used for # libraries. @@ -161,6 +161,10 @@ Patch34: glibc-upstream-2.33-3.patch Patch35: glibc-upstream-2.33-4.patch Patch36: glibc-upstream-2.33-5.patch Patch37: glibc-upstream-2.33-6.patch +Patch38: glibc-upstream-2.33-7.patch +Patch39: glibc-upstream-2.33-8.patch +Patch40: glibc-upstream-2.33-9.patch +Patch41: glibc-upstream-2.33-10.patch ############################################################################## # Continued list of core "glibc" package information: @@ -2296,6 +2300,18 @@ fi %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared %changelog +* Thu Mar 4 2021 Florian Weimer - 2.33-4 +- Import patch from the upstream glibc 2.33 branch, up to commit + 3e880d733753183696d1a81c34caef3a9add2b0c. +- nss: Re-enable NSS module loading after chroot [BZ #27389] + +* Tue Mar 2 2021 Florian Weimer - 2.33-3 +- Import patches from the upstream glibc 2.33 branch, up to commit + 71b2463f6178a6097532dcfe8948bffbe2376dfb. +- x86: Add CPU-specific diagnostics to ld.so --list-diagnostics +- x86: Automate generation of PREFERRED_FEATURE_INDEX_1 bitfield +- ld.so: Implement the --list-diagnostics option + * Fri Feb 19 2021 Florian Weimer - 2.33-2 - Re-enable -Werror; GCC PR 98512 workaround applied upstream - Import patches from the upstream glibc 2.33 branch, up to commit