From a4795185b8329434dd04c3042e04763bf0c9d301 Mon Sep 17 00:00:00 2001 From: aekoroglu Date: Feb 09 2023 12:41:04 +0000 Subject: RHBZ #2154914 --- diff --git a/SOURCES/glibc-rh2154914-1.patch b/SOURCES/glibc-rh2154914-1.patch new file mode 100644 index 0000000..3eafe16 --- /dev/null +++ b/SOURCES/glibc-rh2154914-1.patch @@ -0,0 +1,297 @@ +Maintain an explicit order of tunables, so that the tunable_list +array and the tunable_id_t constant can remain consistent over time. + +Related to this upstream bug: + + Internal tunables ABI depends on awk array iteration order + + +The new dl-tunables.list files are already on the sysdeps search +path, which is why the existing Makeconfig rule picks them up. +The files for RHEL 8.7.z were created by applying the gen-tunables.awk +part of this patch to RHEL 8.7.0 (glibc-2.28-211.el8_7, to be precise). +The sysdeps/unix/sysv/linux/**/dl-tunables.list files were created +based on the generated error message during the RHEL 8.7.z build. +Afterwards, the glibc.rtld.dynamic_sort tunable was added at the +end of the files, for the RHEL 8.8.0 build. + +Going forward, new tunables will have to be added manually to the end +of those files. Existing tunables should not be deleted. For +deletion, the script would have to be extended to be able to create +gaps in the tunable_list array. + +diff --git a/scripts/gen-tunables.awk b/scripts/gen-tunables.awk +index 622199061a140ccd..8ebfb560976ead41 100644 +--- a/scripts/gen-tunables.awk ++++ b/scripts/gen-tunables.awk +@@ -12,6 +12,7 @@ BEGIN { + tunable="" + ns="" + top_ns="" ++ tunable_order_count = 0 + } + + # Skip over blank lines and comments. +@@ -78,6 +79,37 @@ $1 == "}" { + next + } + ++$1 == "@order" { ++ if (top_ns != "") { ++ printf("%s:%d: error: invalid @order directive inside namespace %s\n", ++ FILENAME, FNR, top_ns) > "/dev/stderr" ++ exit 1 ++ } ++ if (NF != 2) { ++ printf("%s:%d: error: invalid argument count in @order directive\n", ++ FILENAME, FNR) > "/dev/stderr" ++ exit 1 ++ } ++ order_arg = $2 ++ if (split(order_arg, indices, /\./) != 3) { ++ printf("%s:%d: error: invalid tunable syntax in @order directive\n", ++ FILENAME, FNR) > "/dev/stderr" ++ exit 1 ++ } ++ t = indices[1] ++ n = indices[2] ++ m = indices[3] ++ if ((t, n, m) in tunable_order) { ++ printf("%s:%d: error: duplicate\"@order %s\"\n" \ ++ FILENAME, FNR, order_arg) > "/dev/stderr" ++ exit 1 ++ } ++ ++tunable_order_count ++ tunable_order[t,n,m] = tunable_order_count ++ tunable_order_list[tunable_order_count] = t SUBSEP n SUBSEP m ++ next ++} ++ + # Everything else, which could either be a tunable without any attributes or a + # tunable attribute. + { +@@ -137,6 +169,31 @@ END { + exit 1 + } + ++ missing_order = 0 ++ for (tnm in types) { ++ if (!(tnm in tunable_order)) { ++ if (!missing_order) { ++ print "error: Missing @order directives:" > "/dev/stderr" ++ missing_order = 1 ++ } ++ split(tnm, indices, SUBSEP) ++ printf("@order %s.%s.%s\n", indices[1], indices[2], indices[3]) \ ++ > "/dev/stderr" ++ } ++ } ++ for (i = 1; i <= tunable_order_count; ++i) { ++ tnm = tunable_order_list[i] ++ if (!(tnm in types)) { ++ split(tnm, indices, SUBSEP) ++ printf("error: tunable in \"@order %s.%s.%s\" not known\n", \ ++ indices[1], indices[2], indices[3]) > "/dev/stderr" ++ missing_order = 1 ++ } ++ } ++ if (missing_order) { ++ exit 1 ++ } ++ + print "/* AUTOGENERATED by gen-tunables.awk. */" + print "#ifndef _TUNABLES_H_" + print "# error \"Do not include this file directly.\"" +@@ -147,7 +204,8 @@ END { + # Now, the enum names + print "\ntypedef enum" + print "{" +- for (tnm in types) { ++ for (i = 1; i <= tunable_order_count; ++i) { ++ tnm = tunable_order_list[i] + split (tnm, indices, SUBSEP); + t = indices[1]; + n = indices[2]; +@@ -159,7 +217,8 @@ END { + # Finally, the tunable list. + print "\n#ifdef TUNABLES_INTERNAL" + print "static tunable_t tunable_list[] attribute_relro = {" +- for (tnm in types) { ++ for (i = 1; i <= tunable_order_count; ++i) { ++ tnm = tunable_order_list[i] + split (tnm, indices, SUBSEP); + t = indices[1]; + n = indices[2]; +diff --git a/sysdeps/unix/sysv/linux/aarch64/dl-tunables.list b/sysdeps/unix/sysv/linux/aarch64/dl-tunables.list +new file mode 100644 +index 0000000000000000..5c3c5292025607a1 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/aarch64/dl-tunables.list +@@ -0,0 +1,26 @@ ++# Order of tunables in RHEL 8.7.0. ++@order glibc.rtld.nns ++@order glibc.elision.skip_lock_after_retries ++@order glibc.malloc.trim_threshold ++@order glibc.malloc.perturb ++@order glibc.cpu.name ++@order glibc.elision.tries ++@order glibc.elision.enable ++@order glibc.malloc.mxfast ++@order glibc.elision.skip_lock_busy ++@order glibc.malloc.top_pad ++@order glibc.cpu.hwcap_mask ++@order glibc.malloc.mmap_max ++@order glibc.elision.skip_trylock_internal_abort ++@order glibc.malloc.tcache_unsorted_limit ++@order glibc.elision.skip_lock_internal_abort ++@order glibc.malloc.arena_max ++@order glibc.malloc.mmap_threshold ++@order glibc.malloc.tcache_count ++@order glibc.malloc.arena_test ++@order glibc.rtld.optional_static_tls ++@order glibc.malloc.tcache_max ++@order glibc.malloc.check ++ ++# Tunables added in RHEL 8.8.0 ++@order glibc.rtld.dynamic_sort +diff --git a/sysdeps/unix/sysv/linux/i386/dl-tunables.list b/sysdeps/unix/sysv/linux/i386/dl-tunables.list +new file mode 100644 +index 0000000000000000..b9cad4af62d9f2e5 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/i386/dl-tunables.list +@@ -0,0 +1,33 @@ ++# Order of tunables in RHEL 8.7.0. ++@order glibc.rtld.nns ++@order glibc.elision.skip_lock_after_retries ++@order glibc.malloc.trim_threshold ++@order glibc.malloc.perturb ++@order glibc.cpu.x86_shared_cache_size ++@order glibc.elision.tries ++@order glibc.elision.enable ++@order glibc.cpu.x86_rep_movsb_threshold ++@order glibc.malloc.mxfast ++@order glibc.elision.skip_lock_busy ++@order glibc.malloc.top_pad ++@order glibc.cpu.x86_rep_stosb_threshold ++@order glibc.cpu.x86_non_temporal_threshold ++@order glibc.cpu.x86_shstk ++@order glibc.cpu.hwcap_mask ++@order glibc.malloc.mmap_max ++@order glibc.elision.skip_trylock_internal_abort ++@order glibc.malloc.tcache_unsorted_limit ++@order glibc.cpu.x86_ibt ++@order glibc.cpu.hwcaps ++@order glibc.elision.skip_lock_internal_abort ++@order glibc.malloc.arena_max ++@order glibc.malloc.mmap_threshold ++@order glibc.cpu.x86_data_cache_size ++@order glibc.malloc.tcache_count ++@order glibc.malloc.arena_test ++@order glibc.rtld.optional_static_tls ++@order glibc.malloc.tcache_max ++@order glibc.malloc.check ++ ++# Tunables added in RHEL 8.8.0 ++@order glibc.rtld.dynamic_sort +diff --git a/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list +new file mode 100644 +index 0000000000000000..ee1e6fca95e1f2da +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/powerpc/powerpc64/le/dl-tunables.list +@@ -0,0 +1,26 @@ ++# Order of tunables in RHEL 8.7.0. ++@order glibc.rtld.nns ++@order glibc.elision.skip_lock_after_retries ++@order glibc.malloc.trim_threshold ++@order glibc.malloc.perturb ++@order glibc.elision.tries ++@order glibc.elision.enable ++@order glibc.malloc.mxfast ++@order glibc.elision.skip_lock_busy ++@order glibc.malloc.top_pad ++@order glibc.cpu.hwcap_mask ++@order glibc.malloc.mmap_max ++@order glibc.elision.skip_trylock_internal_abort ++@order glibc.malloc.tcache_unsorted_limit ++@order glibc.elision.skip_lock_internal_abort ++@order glibc.malloc.arena_max ++@order glibc.malloc.mmap_threshold ++@order glibc.cpu.cached_memopt ++@order glibc.malloc.tcache_count ++@order glibc.malloc.arena_test ++@order glibc.rtld.optional_static_tls ++@order glibc.malloc.tcache_max ++@order glibc.malloc.check ++ ++# Tunables added in RHEL 8.8.0 ++@order glibc.rtld.dynamic_sort +diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/dl-tunables.list b/sysdeps/unix/sysv/linux/s390/s390-64/dl-tunables.list +new file mode 100644 +index 0000000000000000..099e28d8f8e67944 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/s390/s390-64/dl-tunables.list +@@ -0,0 +1,25 @@ ++# Order of tunables in RHEL 8.7.0. ++@order glibc.rtld.nns ++@order glibc.elision.skip_lock_after_retries ++@order glibc.malloc.trim_threshold ++@order glibc.malloc.perturb ++@order glibc.elision.tries ++@order glibc.elision.enable ++@order glibc.malloc.mxfast ++@order glibc.elision.skip_lock_busy ++@order glibc.malloc.top_pad ++@order glibc.cpu.hwcap_mask ++@order glibc.malloc.mmap_max ++@order glibc.elision.skip_trylock_internal_abort ++@order glibc.malloc.tcache_unsorted_limit ++@order glibc.elision.skip_lock_internal_abort ++@order glibc.malloc.arena_max ++@order glibc.malloc.mmap_threshold ++@order glibc.malloc.tcache_count ++@order glibc.malloc.arena_test ++@order glibc.rtld.optional_static_tls ++@order glibc.malloc.tcache_max ++@order glibc.malloc.check ++ ++# Tunables added in RHEL 8.8.0 ++@order glibc.rtld.dynamic_sort +diff --git a/sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list b/sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list +new file mode 100644 +index 0000000000000000..b9cad4af62d9f2e5 +--- /dev/null ++++ b/sysdeps/unix/sysv/linux/x86_64/64/dl-tunables.list +@@ -0,0 +1,33 @@ ++# Order of tunables in RHEL 8.7.0. ++@order glibc.rtld.nns ++@order glibc.elision.skip_lock_after_retries ++@order glibc.malloc.trim_threshold ++@order glibc.malloc.perturb ++@order glibc.cpu.x86_shared_cache_size ++@order glibc.elision.tries ++@order glibc.elision.enable ++@order glibc.cpu.x86_rep_movsb_threshold ++@order glibc.malloc.mxfast ++@order glibc.elision.skip_lock_busy ++@order glibc.malloc.top_pad ++@order glibc.cpu.x86_rep_stosb_threshold ++@order glibc.cpu.x86_non_temporal_threshold ++@order glibc.cpu.x86_shstk ++@order glibc.cpu.hwcap_mask ++@order glibc.malloc.mmap_max ++@order glibc.elision.skip_trylock_internal_abort ++@order glibc.malloc.tcache_unsorted_limit ++@order glibc.cpu.x86_ibt ++@order glibc.cpu.hwcaps ++@order glibc.elision.skip_lock_internal_abort ++@order glibc.malloc.arena_max ++@order glibc.malloc.mmap_threshold ++@order glibc.cpu.x86_data_cache_size ++@order glibc.malloc.tcache_count ++@order glibc.malloc.arena_test ++@order glibc.rtld.optional_static_tls ++@order glibc.malloc.tcache_max ++@order glibc.malloc.check ++ ++# Tunables added in RHEL 8.8.0 ++@order glibc.rtld.dynamic_sort diff --git a/SOURCES/glibc-rh2154914-2.patch b/SOURCES/glibc-rh2154914-2.patch new file mode 100644 index 0000000..4c89744 --- /dev/null +++ b/SOURCES/glibc-rh2154914-2.patch @@ -0,0 +1,81 @@ +Move _dl_dso_sort_algo out of _rtld_global_ro. It is only used +locally in elf/dl-sort-maps.c. This avoids changing the internal +_rtld_global_ro ABI. + +diff --git a/elf/dl-sort-maps.c b/elf/dl-sort-maps.c +index 6f5c17b47b98fbc7..aeb79b40b45054c0 100644 +--- a/elf/dl-sort-maps.c ++++ b/elf/dl-sort-maps.c +@@ -290,12 +290,21 @@ _dl_sort_maps_dfs (struct link_map **maps, unsigned int nmaps, + } + } + ++/* DSO sort algorithm to use. */ ++enum dso_sort_algorithm ++ { ++ dso_sort_algorithm_original, ++ dso_sort_algorithm_dfs ++ }; ++ ++static enum dso_sort_algorithm _dl_dso_sort_algo; ++ + void + _dl_sort_maps_init (void) + { + int32_t algorithm = TUNABLE_GET (glibc, rtld, dynamic_sort, int32_t, NULL); +- GLRO(dl_dso_sort_algo) = algorithm == 1 ? dso_sort_algorithm_original +- : dso_sort_algorithm_dfs; ++ _dl_dso_sort_algo = (algorithm == 1 ? dso_sort_algorithm_original ++ : dso_sort_algorithm_dfs); + } + + void +@@ -309,7 +318,7 @@ _dl_sort_maps (struct link_map **maps, unsigned int nmaps, + PTR_MANGLE/DEMANGLE, further impairing performance of small, common + input cases. A simple if-case with direct function calls appears to + be the fastest. */ +- if (__glibc_likely (GLRO(dl_dso_sort_algo) == dso_sort_algorithm_original)) ++ if (__glibc_likely (_dl_dso_sort_algo == dso_sort_algorithm_original)) + _dl_sort_maps_original (maps, nmaps, force_first, for_fini); + else + _dl_sort_maps_dfs (maps, nmaps, force_first, for_fini); +diff --git a/elf/dl-support.c b/elf/dl-support.c +index ae03aec9764e29d3..e9943e889ef447ad 100644 +--- a/elf/dl-support.c ++++ b/elf/dl-support.c +@@ -155,8 +155,6 @@ size_t _dl_phnum; + uint64_t _dl_hwcap __attribute__ ((nocommon)); + uint64_t _dl_hwcap2 __attribute__ ((nocommon)); + +-enum dso_sort_algorithm _dl_dso_sort_algo; +- + /* The value of the FPU control word the kernel will preset in hardware. */ + fpu_control_t _dl_fpu_control = _FPU_DEFAULT; + +diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h +index 2c1b4c47c6a6c643..29bbde3e83e37d7e 100644 +--- a/sysdeps/generic/ldsodefs.h ++++ b/sysdeps/generic/ldsodefs.h +@@ -240,13 +240,6 @@ enum allowmask + }; + + +-/* DSO sort algorithm to use (check dl-sort-maps.c). */ +-enum dso_sort_algorithm +- { +- dso_sort_algorithm_original, +- dso_sort_algorithm_dfs +- }; +- + struct audit_ifaces + { + void (*activity) (uintptr_t *, unsigned int); +@@ -640,8 +633,6 @@ struct rtld_global_ro + platforms. */ + EXTERN uint64_t _dl_hwcap2; + +- EXTERN enum dso_sort_algorithm _dl_dso_sort_algo; +- + #ifdef SHARED + /* We add a function table to _rtld_global which is then used to + call the function instead of going through the PLT. The result diff --git a/SPECS/glibc.spec b/SPECS/glibc.spec index e35ae64..a1fcd8a 100644 --- a/SPECS/glibc.spec +++ b/SPECS/glibc.spec @@ -1,6 +1,6 @@ %define glibcsrcdir glibc-2.28 %define glibcversion 2.28 -%define glibcrelease 226%{?dist} +%define glibcrelease 227%{?dist} # Pre-release tarballs are pulled in from git using a command that is # effectively: # @@ -1029,6 +1029,8 @@ Patch836: glibc-rh2142937-1.patch Patch837: glibc-rh2142937-2.patch Patch838: glibc-rh2142937-3.patch Patch839: glibc-rh2144568.patch +Patch840: glibc-rh2154914-1.patch +Patch841: glibc-rh2154914-2.patch # Intel Optimizations Patch10001: glibc-sw24097-1.patch @@ -2974,6 +2976,9 @@ fi %files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared %changelog +* Fri Jan 20 2023 Florian Weimer - 2.28-227 +- Enforce a specififc internal ordering for tunables (#2154914) + * Wed Nov 30 2022 Arjun Shankar - 2.28-226 - Fix rtld-audit trampoline for aarch64 (#2144568)