From d6c4ca2157461b3eacaa3c3a0d4c39851c2a9b05 Mon Sep 17 00:00:00 2001 From: Pavel Valena Date: Wed, 28 Aug 2024 18:36:00 +0200 Subject: [PATCH] Resolves: RHEL-43460 Additional fix to avoid regression: https://github.com/dracut-ng/dracut-ng/pull/590#issuecomment-2301382666 From-source-git-commit: fa245cea3b5f03d24777e9cbf6f295977541565c --- ...it.sh-add-module-to-mods_to_load-bef.patch | 73 ++++ ...-fix-squash-remove-cyclic-dependency.patch | 313 ++++++++++++++++++ ...it-when-installing-the-squash-loader.patch | 38 +++ ...ash-lib-harden-against-empty-initdir.patch | 40 +++ dracut.spec | 22 +- 5 files changed, 485 insertions(+), 1 deletion(-) create mode 100644 0032-revert-dracut-init.sh-add-module-to-mods_to_load-bef.patch create mode 100644 0033-fix-squash-remove-cyclic-dependency.patch create mode 100644 0034-fix-dracut.sh-exit-when-installing-the-squash-loader.patch create mode 100644 0035-fix-squash-lib-harden-against-empty-initdir.patch diff --git a/0032-revert-dracut-init.sh-add-module-to-mods_to_load-bef.patch b/0032-revert-dracut-init.sh-add-module-to-mods_to_load-bef.patch new file mode 100644 index 0000000..16ced21 --- /dev/null +++ b/0032-revert-dracut-init.sh-add-module-to-mods_to_load-bef.patch @@ -0,0 +1,73 @@ +From 7a580a481f8b2d2df60a5e7b9da5c4a11ed9ecbf Mon Sep 17 00:00:00 2001 +From: Philipp Rudo +Date: Mon, 26 Aug 2024 15:58:54 +0200 +Subject: [PATCH 32/35] revert(dracut-init.sh): add module to mods_to_load + before checking dependencies + +Commit d0f8fde5 ("fix(dracut-init.sh): add module to mods_to_load before +checking dependencies") introduced a regression. When dracut is in +"auto" mode, i.e. '--modules auto' or no --modules is provided, the +expected behavior is that all modules that return 0 in their check() +function are included. Except for the ones where the dependencies cannot +be installed. The commit however, caused those modules to be included +without their dependencies. Thus revert the commit. + +This reverts commit d0f8fde5668cfd7fda1d15824e268b4949b4fd04. + +Reported-by: Jo Zzsi +Signed-off-by: Philipp Rudo + +(cherry picked from commit bddbb11bbbfc405317a6fbd53bb189b575d46da2) + +Resolves: RHEL-43460 +--- + dracut-init.sh | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/dracut-init.sh b/dracut-init.sh +index 5d5fc081..756a0a75 100755 +--- a/dracut-init.sh ++++ b/dracut-init.sh +@@ -915,9 +915,6 @@ check_mount() { + fi + fi + +- [[ " $mods_to_load " == *\ $_mod\ * ]] \ +- || mods_to_load+=" $_mod " +- + for _moddep in $(module_depends "$_mod" "$_moddir"); do + # handle deps as if they were manually added + [[ " $dracutmodules " == *\ $_mod\ * ]] \ +@@ -936,6 +933,9 @@ check_mount() { + fi + done + ++ [[ " $mods_to_load " == *\ $_mod\ * ]] \ ++ || mods_to_load+=" $_mod " ++ + return 0 + } + +@@ -992,9 +992,6 @@ check_module() { + fi + fi + +- [[ " $mods_to_load " == *\ $_mod\ * ]] \ +- || mods_to_load+=" $_mod " +- + for _moddep in $(module_depends "$_mod" "$_moddir"); do + # handle deps as if they were manually added + [[ " $dracutmodules " == *\ $_mod\ * ]] \ +@@ -1013,6 +1010,9 @@ check_module() { + fi + done + ++ [[ " $mods_to_load " == *\ $_mod\ * ]] \ ++ || mods_to_load+=" $_mod " ++ + return 0 + } + +-- +2.42.0 + diff --git a/0033-fix-squash-remove-cyclic-dependency.patch b/0033-fix-squash-remove-cyclic-dependency.patch new file mode 100644 index 0000000..8ee18e9 --- /dev/null +++ b/0033-fix-squash-remove-cyclic-dependency.patch @@ -0,0 +1,313 @@ +From 7e1598536003caf9c6b68e9a4eaf3cef8bfcfeb9 Mon Sep 17 00:00:00 2001 +From: Philipp Rudo +Date: Mon, 26 Aug 2024 15:23:41 +0200 +Subject: [PATCH 33/35] fix(squash): remove cyclic dependency + +With commit d0f8fde5 ("fix(dracut-init.sh): add module to mods_to_load +before checking dependencies") reverted 99squash can no longer rely on +dracut_module_included working as expected in its check() and depends() +function. Solve this problem by breaking up the cyclic dependency +between 99squash and 95squash-{squashfs,erofs} as the commit was +originally introduced to allow this cyclic dependency. + +This requires to move all code shared by 95squash-{squashfs,erofs} from +99squash to a new 99squash-lib module and update the dependencies +accordingly. In addition update the checks in dracut.sh to check for +99squash-lib as 99squash is no longer guaranteed to be included. +Finally make sure that 99squash-lib isn't included without a back +end. + +While at it improve and align the error messages in 99squash and +99squash-lib. + +Signed-off-by: Philipp Rudo +(cherry picked from commit d5783635950e38cccf334e7163db79f280650fa2) + +Resolves: RHEL-43460 +--- + dracut.sh | 6 +- + modules.d/95squash-erofs/module-setup.sh | 2 +- + modules.d/95squash-squashfs/module-setup.sh | 2 +- + .../{99squash => 99squash-lib}/init-squash.sh | 0 + modules.d/99squash-lib/module-setup.sh | 101 ++++++++++++++++++ + modules.d/99squash/module-setup.sh | 80 +------------- + 6 files changed, 110 insertions(+), 81 deletions(-) + rename modules.d/{99squash => 99squash-lib}/init-squash.sh (100%) + create mode 100755 modules.d/99squash-lib/module-setup.sh + +diff --git a/dracut.sh b/dracut.sh +index 68bdf33b..71568fe0 100755 +--- a/dracut.sh ++++ b/dracut.sh +@@ -1911,7 +1911,7 @@ if [[ $kernel_only != yes ]]; then + fi + fi + +-dracut_module_included "squash" && mkdir -p "$squashdir" ++dracut_module_included "squash-lib" && mkdir -p "$squashdir" + + _isize=0 #initramfs size + modules_loaded=" " +@@ -2276,9 +2276,9 @@ if [[ $do_strip == yes ]] && ! [[ $DRACUT_FIPS_MODE ]]; then + dinfo "*** Stripping files done ***" + fi + +-if dracut_module_included "squash"; then ++if dracut_module_included "squash-lib"; then + dinfo "*** Squashing the files inside the initramfs ***" +- DRACUT_SQUASH_POST_INST=1 module_install "squash" ++ DRACUT_SQUASH_POST_INST=1 module_install "squash-lib" + rm -rf "$squashdir" + dinfo "*** Squashing the files inside the initramfs done ***" + +diff --git a/modules.d/95squash-erofs/module-setup.sh b/modules.d/95squash-erofs/module-setup.sh +index d763a902..a6e7ad0b 100755 +--- a/modules.d/95squash-erofs/module-setup.sh ++++ b/modules.d/95squash-erofs/module-setup.sh +@@ -8,7 +8,7 @@ check() { + } + + depends() { +- echo "squash" ++ echo "squash-lib" + return 0 + } + +diff --git a/modules.d/95squash-squashfs/module-setup.sh b/modules.d/95squash-squashfs/module-setup.sh +index 83973700..d15586da 100755 +--- a/modules.d/95squash-squashfs/module-setup.sh ++++ b/modules.d/95squash-squashfs/module-setup.sh +@@ -8,7 +8,7 @@ check() { + } + + depends() { +- echo "squash" ++ echo "squash-lib" + return 0 + } + +diff --git a/modules.d/99squash/init-squash.sh b/modules.d/99squash-lib/init-squash.sh +similarity index 100% +rename from modules.d/99squash/init-squash.sh +rename to modules.d/99squash-lib/init-squash.sh +diff --git a/modules.d/99squash-lib/module-setup.sh b/modules.d/99squash-lib/module-setup.sh +new file mode 100755 +index 00000000..6a0b6f85 +--- /dev/null ++++ b/modules.d/99squash-lib/module-setup.sh +@@ -0,0 +1,101 @@ ++#!/bin/bash ++ ++check() { ++ require_kernel_modules loop overlay || return 1 ++ ++ return 255 ++} ++ ++depends() { ++ echo "systemd-initrd" ++ ++ return 0 ++} ++ ++squash_get_handler() { ++ local _module _handler ++ local -a _modules=(squash-squashfs squash-erofs) ++ ++ for _module in "${_modules[@]}"; do ++ if dracut_module_included "$_module"; then ++ _handler="$_module" ++ break ++ fi ++ done ++ ++ if [[ -z $_handler ]]; then ++ dfatal "Cannot include squash-lib directly. It requires one of: ${_modules[*]}" ++ return 1 ++ fi ++ ++ echo "$_handler" ++} ++ ++squash_install() { ++ local _busybox _dir ++ ++ # verify that there is a valid handler before doing anything ++ squash_get_handler > /dev/null || return 1 ++ ++ _busybox=$(find_binary busybox) ++ ++ # Create mount points for squash loader and basic directories ++ mkdir -p "$initdir"/squash ++ for _dir in squash usr/bin usr/sbin usr/lib; do ++ mkdir -p "$squashdir/$_dir" ++ [[ $_dir == usr/* ]] && ln_r "/$_dir" "${_dir#usr}" ++ done ++ ++ # Install required modules and binaries for the squash image init script. ++ if [[ $_busybox ]]; then ++ module_install "busybox" ++ else ++ DRACUT_RESOLVE_DEPS=1 inst_multiple sh mount modprobe mkdir switch_root grep umount ++ ++ # libpthread workaround: pthread_cancel wants to dlopen libgcc_s.so ++ inst_libdir_file -o "libgcc_s.so*" ++ ++ # FIPS workaround for Fedora/RHEL: libcrypto needs libssl when FIPS is enabled ++ [[ $DRACUT_FIPS_MODE ]] && inst_libdir_file -o "libssl.so*" ++ fi ++ ++ hostonly="" instmods "loop" "overlay" ++ dracut_kernel_post ++ ++ # Install squash image init script. ++ inst_simple "$moddir"/init-squash.sh /init ++ ++ # make sure that library links are correct and up to date for squash loader ++ build_ld_cache ++} ++ ++squash_installpost() { ++ local _file _handler ++ ++ _handler=$(squash_get_handler) ++ [[ -n $_handler ]] || return 1 ++ ++ DRACUT_SQUASH_POST_INST=1 module_install "$_handler" ++ ++ # Rescue the dracut spec files so dracut rebuild and lsinitrd can work ++ for _file in "$initdir"/usr/lib/dracut/*; do ++ [[ -f $_file ]] || continue ++ DRACUT_RESOLVE_DEPS=1 dstdir=$squashdir inst "$_file" "${_file#"$initdir"}" ++ done ++ ++ # Remove everything that got squashed into the image ++ for _file in "$initdir"/*; do ++ [[ $_file == "$squashdir" ]] && continue ++ rm -rf "$_file" ++ done ++ mv "$squashdir"/* "$initdir" ++} ++ ++install() { ++ ++ if [[ $DRACUT_SQUASH_POST_INST ]]; then ++ squash_installpost ++ else ++ dstdir="$squashdir" squash_install ++ fi ++} +diff --git a/modules.d/99squash/module-setup.sh b/modules.d/99squash/module-setup.sh +index 56f70774..c48ba2c5 100755 +--- a/modules.d/99squash/module-setup.sh ++++ b/modules.d/99squash/module-setup.sh +@@ -1,102 +1,30 @@ + #!/bin/bash + + check() { +- require_kernel_modules loop overlay || return 1 +- + return 255 + } + + depends() { +- local _handler +- +- _handler=$(squash_get_handler) || return 1 +- +- echo "systemd-initrd $_handler" +- return 0 +-} +- +-squash_get_handler() { + local _module _handler ++ local -a _modules=(squash-squashfs squash-erofs) + +- for _module in squash-squashfs squash-erofs; do ++ for _module in "${_modules[@]}"; do + if dracut_module_included "$_module"; then + _handler="$_module" + break + fi + done + +- if [ -z "$_handler" ]; then ++ if [[ -z $_handler ]]; then + if check_module "squash-squashfs"; then + _handler="squash-squashfs" + elif check_module "squash-erofs"; then + _handler="squash-erofs" + else +- dfatal "No valid handler for found" ++ dfatal "Cannot find valid handler for squash. It requires one of: ${_modules[*]}" + return 1 + fi + fi + + echo "$_handler" + } +- +-squash_install() { +- local _busybox _dir +- _busybox=$(find_binary busybox) +- +- # Create mount points for squash loader and basic directories +- mkdir -p "$initdir"/squash +- for _dir in squash usr/bin usr/sbin usr/lib; do +- mkdir -p "$squashdir/$_dir" +- [[ $_dir == usr/* ]] && ln_r "/$_dir" "${_dir#usr}" +- done +- +- # Install required modules and binaries for the squash image init script. +- if [[ $_busybox ]]; then +- module_install "busybox" +- else +- DRACUT_RESOLVE_DEPS=1 inst_multiple sh mount modprobe mkdir switch_root grep umount +- +- # libpthread workaround: pthread_cancel wants to dlopen libgcc_s.so +- inst_libdir_file -o "libgcc_s.so*" +- +- # FIPS workaround for Fedora/RHEL: libcrypto needs libssl when FIPS is enabled +- [[ $DRACUT_FIPS_MODE ]] && inst_libdir_file -o "libssl.so*" +- fi +- +- hostonly="" instmods "loop" "overlay" +- dracut_kernel_post +- +- # Install squash image init script. +- inst_simple "$moddir"/init-squash.sh /init +- +- # make sure that library links are correct and up to date for squash loader +- build_ld_cache +-} +- +-squash_installpost() { +- local _file +- +- DRACUT_SQUASH_POST_INST=1 module_install "$(squash_get_handler)" +- +- # Rescue the dracut spec files so dracut rebuild and lsinitrd can work +- for _file in "$initdir"/usr/lib/dracut/*; do +- [[ -f $_file ]] || continue +- DRACUT_RESOLVE_DEPS=1 dstdir=$squashdir inst "$_file" "${_file#"$initdir"}" +- done +- +- # Remove everything that got squashed into the image +- for _file in "$initdir"/*; do +- [[ $_file == "$squashdir" ]] && continue +- rm -rf "$_file" +- done +- mv "$squashdir"/* "$initdir" +-} +- +-install() { +- +- if [[ $DRACUT_SQUASH_POST_INST ]]; then +- squash_installpost +- else +- dstdir="$squashdir" squash_install +- fi +-} +-- +2.42.0 + diff --git a/0034-fix-dracut.sh-exit-when-installing-the-squash-loader.patch b/0034-fix-dracut.sh-exit-when-installing-the-squash-loader.patch new file mode 100644 index 0000000..6b6a3e6 --- /dev/null +++ b/0034-fix-dracut.sh-exit-when-installing-the-squash-loader.patch @@ -0,0 +1,38 @@ +From 8fe64408bd8349e28b7257f93880527a93c63fa2 Mon Sep 17 00:00:00 2001 +From: Philipp Rudo +Date: Tue, 27 Aug 2024 12:14:40 +0200 +Subject: [PATCH 34/35] fix(dracut.sh): exit when installing the squash loader + fails + +The postinstall phase in 99squash-lib can fail, e.g. when 99squash-lib +is added without one of the required back ends. Usually this isn't fatal +and simply results in a "normal" initrd, i.e. one without squashed +image, being created. Nevertheless, a user needs to explicitly add one +of the required modules for the code to be triggered. So it is better +to fail with an error rather than giving the user something he didn't +ask for. + +Signed-off-by: Philipp Rudo +(cherry picked from commit 8909d892a7a055ae95be45416e6fbf1b833ff426) + +Resolves: RHEL-43460 +--- + dracut.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dracut.sh b/dracut.sh +index 71568fe0..3d73fe43 100755 +--- a/dracut.sh ++++ b/dracut.sh +@@ -2278,7 +2278,7 @@ fi + + if dracut_module_included "squash-lib"; then + dinfo "*** Squashing the files inside the initramfs ***" +- DRACUT_SQUASH_POST_INST=1 module_install "squash-lib" ++ DRACUT_SQUASH_POST_INST=1 module_install "squash-lib" || exit 1 + rm -rf "$squashdir" + dinfo "*** Squashing the files inside the initramfs done ***" + +-- +2.42.0 + diff --git a/0035-fix-squash-lib-harden-against-empty-initdir.patch b/0035-fix-squash-lib-harden-against-empty-initdir.patch new file mode 100644 index 0000000..5d36886 --- /dev/null +++ b/0035-fix-squash-lib-harden-against-empty-initdir.patch @@ -0,0 +1,40 @@ +From 85235ab58df8343a1a0314333b360648a5d0f452 Mon Sep 17 00:00:00 2001 +From: Philipp Rudo +Date: Mon, 26 Aug 2024 15:29:01 +0200 +Subject: [PATCH 35/35] fix(squash-lib): harden against empty $initdir + +The postinstall phase of 99squash-lib has the potential to delete the +whole rootfs if $initdir is empty. This should(tm) never happen. +Nevertheless as the consequences are so devastating it is better to +double check. + +Signed-off-by: Philipp Rudo +(cherry picked from commit 6b089c70761c81a7b82a1bfba5f2c1faef7e972f) + +Resolves: RHEL-43460 +--- + modules.d/99squash-lib/module-setup.sh | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/modules.d/99squash-lib/module-setup.sh b/modules.d/99squash-lib/module-setup.sh +index 6a0b6f85..be3d3dc0 100755 +--- a/modules.d/99squash-lib/module-setup.sh ++++ b/modules.d/99squash-lib/module-setup.sh +@@ -72,6 +72,14 @@ squash_install() { + squash_installpost() { + local _file _handler + ++ # this shouldn't happen but... ++ # ...better safe than deleting your rootfs ++ if [[ -z $initdir ]]; then ++ #shellcheck disable=SC2016 ++ dfatal '$initdir not set. Something went terribly wrong.' ++ exit 1 ++ fi ++ + _handler=$(squash_get_handler) + [[ -n $_handler ]] || return 1 + +-- +2.42.0 + diff --git a/dracut.spec b/dracut.spec index 33f33db..13d4502 100644 --- a/dracut.spec +++ b/dracut.spec @@ -8,7 +8,7 @@ Name: dracut Version: 102 -Release: 2%{?dist} +Release: 3%{?dist} Summary: Initramfs generator using udev @@ -115,6 +115,18 @@ Patch30: 0030-fix-nfs-include-also-entries-from-usr-lib-passwd-gro.patch # fix(dracut-functions): avoid awk in get_maj_min() # Author: Daniel McIlvaney Patch31: 0031-fix-dracut-functions-avoid-awk-in-get_maj_min.patch +# revert(dracut-init.sh): add module to mods_to_load before checking dependencies +# Author: Philipp Rudo +Patch32: 0032-revert-dracut-init.sh-add-module-to-mods_to_load-bef.patch +# fix(squash): remove cyclic dependency +# Author: Philipp Rudo +Patch33: 0033-fix-squash-remove-cyclic-dependency.patch +# fix(dracut.sh): exit when installing the squash loader fails +# Author: Philipp Rudo +Patch34: 0034-fix-dracut.sh-exit-when-installing-the-squash-loader.patch +# fix(squash-lib): harden against empty $initdir +# Author: Philipp Rudo +Patch35: 0035-fix-squash-lib-harden-against-empty-initdir.patch # Please use source-git to work with this spec file: # HowTo: https://packit.dev/source-git/work-with-source-git @@ -511,6 +523,7 @@ echo 'dracut_rescue_image="yes"' > $RPM_BUILD_ROOT%{dracutlibdir}/dracut.conf.d/ %files squash %{dracutlibdir}/modules.d/99squash +%{dracutlibdir}/modules.d/99squash-lib %{dracutlibdir}/modules.d/95squash-erofs %{dracutlibdir}/modules.d/95squash-squashfs @@ -522,6 +535,13 @@ echo 'dracut_rescue_image="yes"' > $RPM_BUILD_ROOT%{dracutlibdir}/dracut.conf.d/ %{_prefix}/lib/kernel/install.d/51-dracut-rescue.install %changelog +* Wed Aug 28 2024 Pavel Valena - 102-3 +- revert(dracut-init.sh): add module to mods_to_load before checking dependencies +- fix(squash): remove cyclic dependency +- fix(dracut.sh): exit when installing the squash loader fails +- fix(squash-lib): harden against empty $initdir + Resolves: RHEL-43460 + * Mon Aug 19 2024 Pavel Valena - 102-2 - fix(nfs): set correct ownership and permissions for statd directory - fix(resume): do not include resume if swap is on netdevice