From 623a62e04e63b93a35476a15b9fee11f042cde24 Mon Sep 17 00:00:00 2001 From: AlmaLinux RelEng Bot Date: Wed, 17 Jun 2026 06:39:49 -0400 Subject: [PATCH] import UBI dracut-107-7.el10_2 --- ...cy-remove-network-legacy-completely-.patch | 1763 +++++++++++++++++ ...e-echo-writes-with-printf-to-prevent.patch | 101 + ...arguments-in-initqueue-hook-script-g.patch | 73 + ...-on-suspicious-shell-metacharacters-.patch | 48 + ...orkd-escape-DHCP-lease-values-in-dhc.patch | 48 + dracut.spec | 31 +- 6 files changed, 2063 insertions(+), 1 deletion(-) create mode 100644 0032-fix-network-legacy-remove-network-legacy-completely-.patch create mode 100644 0033-fix-iscsi-replace-echo-writes-with-printf-to-prevent.patch create mode 100644 0034-fix-base-escape-arguments-in-initqueue-hook-script-g.patch create mode 100644 0035-fix-net-lib-warn-on-suspicious-shell-metacharacters-.patch create mode 100644 0036-fix-systemd-networkd-escape-DHCP-lease-values-in-dhc.patch diff --git a/0032-fix-network-legacy-remove-network-legacy-completely-.patch b/0032-fix-network-legacy-remove-network-legacy-completely-.patch new file mode 100644 index 0000000..8497cb4 --- /dev/null +++ b/0032-fix-network-legacy-remove-network-legacy-completely-.patch @@ -0,0 +1,1763 @@ +From 2a3570c11080aa493c309af43a547914668aef1f Mon Sep 17 00:00:00 2001 +From: Pavel Valena +Date: Thu, 7 May 2026 00:40:31 +0200 +Subject: [PATCH 32/34] fix(network-legacy): remove network-legacy completely + from the codebase + +(To not rely solely on a dracut.spec file.) + +Resolves: RHEL-170844 +--- + modules.d/35network-legacy/dhclient-script.sh | 275 --------- + modules.d/35network-legacy/dhclient.conf | 11 - + modules.d/35network-legacy/dhcp-multi.sh | 133 ----- + modules.d/35network-legacy/ifup.sh | 562 ------------------ + modules.d/35network-legacy/kill-dhclient.sh | 15 - + modules.d/35network-legacy/module-setup.sh | 102 ---- + modules.d/35network-legacy/net-genrules.sh | 125 ---- + modules.d/35network-legacy/parse-bond.sh | 76 --- + modules.d/35network-legacy/parse-bridge.sh | 49 -- + modules.d/35network-legacy/parse-ibft.sh | 10 - + modules.d/35network-legacy/parse-ifname.sh | 24 - + modules.d/35network-legacy/parse-ip-opts.sh | 151 ----- + modules.d/35network-legacy/parse-team.sh | 66 -- + modules.d/35network-legacy/parse-vlan.sh | 37 -- + 14 files changed, 1636 deletions(-) + delete mode 100755 modules.d/35network-legacy/dhclient-script.sh + delete mode 100644 modules.d/35network-legacy/dhclient.conf + delete mode 100755 modules.d/35network-legacy/dhcp-multi.sh + delete mode 100755 modules.d/35network-legacy/ifup.sh + delete mode 100755 modules.d/35network-legacy/kill-dhclient.sh + delete mode 100755 modules.d/35network-legacy/module-setup.sh + delete mode 100755 modules.d/35network-legacy/net-genrules.sh + delete mode 100755 modules.d/35network-legacy/parse-bond.sh + delete mode 100755 modules.d/35network-legacy/parse-bridge.sh + delete mode 100755 modules.d/35network-legacy/parse-ibft.sh + delete mode 100755 modules.d/35network-legacy/parse-ifname.sh + delete mode 100755 modules.d/35network-legacy/parse-ip-opts.sh + delete mode 100755 modules.d/35network-legacy/parse-team.sh + delete mode 100755 modules.d/35network-legacy/parse-vlan.sh + +diff --git a/modules.d/35network-legacy/dhclient-script.sh b/modules.d/35network-legacy/dhclient-script.sh +deleted file mode 100755 +index 6751f2d6..00000000 +--- a/modules.d/35network-legacy/dhclient-script.sh ++++ /dev/null +@@ -1,275 +0,0 @@ +-#!/bin/sh +- +-PATH=/usr/sbin:/usr/bin:/sbin:/bin +- +-command -v getarg > /dev/null || . /lib/dracut-lib.sh +-command -v ip_to_var > /dev/null || . /lib/net-lib.sh +- +-# We already need a set netif here +-netif=$interface +- +-setup_interface() { +- ip=$new_ip_address +- mtu=$new_interface_mtu +- mask=$new_subnet_mask +- bcast=$new_broadcast_address +- gw=${new_routers%%,*} +- domain=$new_domain_name +- # get rid of control chars +- search=$(printf -- "%s" "$new_domain_search" | tr -d '[:cntrl:]') +- namesrv=$new_domain_name_servers +- hostname=$new_host_name +- [ -n "$new_dhcp_lease_time" ] && lease_time=$new_dhcp_lease_time +- [ -n "$new_max_life" ] && lease_time=$new_max_life +- preferred_lft=$lease_time +- [ -n "$new_preferred_life" ] && preferred_lft=$new_preferred_life +- +- # shellcheck disable=SC1090 +- [ -f /tmp/net."$netif".override ] && . /tmp/net."$netif".override +- +- # Taken from debian dhclient-script: +- # The 576 MTU is only used for X.25 and dialup connections +- # where the admin wants low latency. Such a low MTU can cause +- # problems with UDP traffic, among other things. As such, +- # disallow MTUs from 576 and below by default, so that broken +- # MTUs are ignored, but higher stuff is allowed (1492, 1500, etc). +- if [ -n "$mtu" ] && [ "$mtu" -gt 576 ]; then +- if ! ip link set "$netif" mtu "$mtu"; then +- ip link set "$netif" down +- ip link set "$netif" mtu "$mtu" +- linkup "$netif" +- fi +- fi +- +- ip addr add "$ip"${mask:+/$mask} ${bcast:+broadcast $bcast} dev "$netif" \ +- ${lease_time:+valid_lft $lease_time} \ +- ${preferred_lft:+preferred_lft ${preferred_lft}} +- +- if [ -n "$gw" ]; then +- if [ "$mask" = "255.255.255.255" ]; then +- # point-to-point connection => set explicit route to gateway +- echo ip route add "$gw" dev "$netif" > /tmp/net."$netif".gw +- fi +- +- echo "$gw" | { +- IFS=' ' read -r main_gw other_gw +- echo ip route replace default via "$main_gw" dev "$netif" >> /tmp/net."$netif".gw +- if [ -n "$other_gw" ]; then +- for g in $other_gw; do +- echo ip route add default via "$g" dev "$netif" >> /tmp/net."$netif".gw +- done +- fi +- } +- fi +- +- if getargbool 1 rd.peerdns; then +- [ -n "${search}${domain}" ] && echo "search $search $domain" > /tmp/net."$netif".resolv.conf +- if [ -n "$namesrv" ]; then +- for s in $namesrv; do +- echo nameserver "$s" +- done +- fi >> /tmp/net."$netif".resolv.conf +- fi +- # Note: hostname can be fqdn OR short hostname, so chop off any +- # trailing domain name and explicitly add any domain if set. +- [ -n "$hostname" ] && echo "echo ${hostname%."$domain"}${domain:+.$domain} > /proc/sys/kernel/hostname" > /tmp/net."$netif".hostname +-} +- +-setup_interface6() { +- domain=$new_domain_name +- # get rid of control chars +- search=$(printf -- "%s" "$new_dhcp6_domain_search" | tr -d '[:cntrl:]') +- namesrv=$new_dhcp6_name_servers +- hostname=$new_host_name +- [ -n "$new_dhcp_lease_time" ] && lease_time=$new_dhcp_lease_time +- [ -n "$new_max_life" ] && lease_time=$new_max_life +- preferred_lft=$lease_time +- [ -n "$new_preferred_life" ] && preferred_lft=$new_preferred_life +- +- # shellcheck disable=SC1090 +- [ -f /tmp/net."$netif".override ] && . /tmp/net."$netif".override +- +- ip -6 addr add "${new_ip6_address}"/"${new_ip6_prefixlen}" \ +- dev "${netif}" scope global \ +- ${lease_time:+valid_lft $lease_time} \ +- ${preferred_lft:+preferred_lft ${preferred_lft}} +- +- if getargbool 1 rd.peerdns; then +- [ -n "${search}${domain}" ] && echo "search $search $domain" > /tmp/net."$netif".resolv.conf +- if [ -n "$namesrv" ]; then +- for s in $namesrv; do +- echo nameserver "$s" +- done +- fi >> /tmp/net."$netif".resolv.conf +- fi +- +- # Note: hostname can be fqdn OR short hostname, so chop off any +- # trailing domain name and explicitly add any domain if set. +- [ -n "$hostname" ] && echo "echo ${hostname%."$domain"}${domain:+.$domain} > /proc/sys/kernel/hostname" > /tmp/net."$netif".hostname +-} +- +-parse_option_121() { +- while [ $# -ne 0 ]; do +- mask="$1" +- shift +- +- # Is the destination a multicast group? +- if [ "$1" -ge 224 ] && [ "$1" -lt 240 ]; then +- multicast=1 +- else +- multicast=0 +- fi +- +- # Parse the arguments into a CIDR net/mask string +- if [ "$mask" -gt 24 ]; then +- destination="$1.$2.$3.$4/$mask" +- shift +- shift +- shift +- shift +- elif [ "$mask" -gt 16 ]; then +- destination="$1.$2.$3.0/$mask" +- shift +- shift +- shift +- elif [ "$mask" -gt 8 ]; then +- destination="$1.$2.0.0/$mask" +- shift +- shift +- elif [ "$mask" -gt 0 ]; then +- destination="$1.0.0.0/$mask" +- shift +- else +- destination="0.0.0.0/$mask" +- fi +- +- # Read the gateway +- gateway="$1.$2.$3.$4" +- shift +- shift +- shift +- shift +- +- # Multicast routing on Linux +- # - If you set a next-hop address for a multicast group, this breaks with Cisco switches +- # - If you simply leave it link-local and attach it to an interface, it works fine. +- if [ $multicast -eq 1 ] || [ "$gateway" = "0.0.0.0" ]; then +- temp_result="$destination dev $interface" +- else +- temp_result="$destination via $gateway dev $interface" +- fi +- +- echo "/sbin/ip route replace $temp_result" +- done +-} +- +-case $reason in +- PREINIT) +- echo "dhcp: PREINIT $netif up" +- linkup "$netif" +- ;; +- +- PREINIT6) +- echo "dhcp: PREINIT6 $netif up" +- linkup "$netif" +- wait_for_ipv6_dad_link "$netif" +- ;; +- +- BOUND) +- echo "dhcp: BOUND setting up $netif" +- unset layer2 +- if [ -f /sys/class/net/"$netif"/device/layer2 ]; then +- read -r layer2 < /sys/class/net/"$netif"/device/layer2 +- fi +- if [ "$layer2" != "0" ]; then +- if command -v arping2 > /dev/null; then +- if arping2 -q -C 1 -c 2 -I "$netif" -0 "$new_ip_address"; then +- warn "Duplicate address detected for $new_ip_address while doing dhcp. retrying" +- exit 1 +- fi +- else +- if ! arping -f -q -D -c 2 -I "$netif" "$new_ip_address"; then +- warn "Duplicate address detected for $new_ip_address while doing dhcp. retrying" +- exit 1 +- fi +- fi +- fi +- unset layer2 +- setup_interface +- set | while read -r line || [ -n "$line" ]; do +- [ "${line#new_}" = "$line" ] && continue +- echo "$line" +- done > /tmp/dhclient."$netif".dhcpopts +- +- { +- echo '. /lib/net-lib.sh' +- echo "setup_net $netif" +- if [ -n "$new_classless_static_routes" ]; then +- OLDIFS="$IFS" +- IFS=".$IFS" +- parse_option_121 "$new_classless_static_routes" +- IFS="$OLDIFS" +- fi +- echo "source_hook initqueue/online $netif" +- [ -e /tmp/net."$netif".manualup ] || echo "/sbin/netroot $netif" +- echo "rm -f -- $hookdir/initqueue/setup_net_$netif.sh" +- } > "$hookdir"/initqueue/setup_net_"$netif".sh +- +- echo "[ -f /tmp/net.$netif.did-setup ]" > "$hookdir"/initqueue/finished/dhclient-"$netif".sh +- : > /tmp/net."$netif".up +- if [ -e /sys/class/net/"${netif}"/address ]; then +- : > "/tmp/net.$(cat /sys/class/net/"${netif}"/address).up" +- fi +- +- ;; +- +- RENEW | REBIND) +- unset lease_time +- [ -n "$new_dhcp_lease_time" ] && lease_time=$new_dhcp_lease_time +- [ -n "$new_max_life" ] && lease_time=$new_max_life +- preferred_lft=$lease_time +- [ -n "$new_preferred_life" ] && preferred_lft=$new_preferred_life +- ip -4 addr change "${new_ip_address}"/"${new_subnet_mask}" broadcast "${new_broadcast_address}" dev "${interface}" \ +- ${lease_time:+valid_lft $lease_time} ${preferred_lft:+preferred_lft ${preferred_lft}} \ +- > /dev/null 2>&1 +- ;; +- +- BOUND6) +- echo "dhcp: BOUND6 setting up $netif" +- setup_interface6 +- +- set | while read -r line || [ -n "$line" ]; do +- [ "${line#new_}" = "$line" ] && continue +- echo "$line" +- done > /tmp/dhclient."$netif".dhcpopts +- +- { +- echo '. /lib/net-lib.sh' +- echo "setup_net $netif" +- echo "source_hook initqueue/online $netif" +- [ -e /tmp/net."$netif".manualup ] || echo "/sbin/netroot $netif" +- echo "rm -f -- $hookdir/initqueue/setup_net_$netif.sh" +- } > "$hookdir"/initqueue/setup_net_"$netif".sh +- +- echo "[ -f /tmp/net.$netif.did-setup ]" > "$hookdir"/initqueue/finished/dhclient-"$netif".sh +- : > /tmp/net."$netif".up +- if [ -e /sys/class/net/"${netif}"/address ]; then +- : > "/tmp/net.$(cat /sys/class/net/"${netif}"/address).up" +- fi +- ;; +- +- RENEW6 | REBIND6) +- unset lease_time +- [ -n "$new_dhcp_lease_time" ] && lease_time=$new_dhcp_lease_time +- [ -n "$new_max_life" ] && lease_time=$new_max_life +- preferred_lft=$lease_time +- [ -n "$new_preferred_life" ] && preferred_lft=$new_preferred_life +- ip -6 addr change "${new_ip6_address}"/"${new_ip6_prefixlen}" dev "${interface}" scope global \ +- ${lease_time:+valid_lft $lease_time} ${preferred_lft:+preferred_lft ${preferred_lft}} \ +- > /dev/null 2>&1 +- ;; +- +- *) echo "dhcp: $reason" ;; +-esac +- +-exit 0 +diff --git a/modules.d/35network-legacy/dhclient.conf b/modules.d/35network-legacy/dhclient.conf +deleted file mode 100644 +index ffd24ef6..00000000 +--- a/modules.d/35network-legacy/dhclient.conf ++++ /dev/null +@@ -1,11 +0,0 @@ +- +-option classless-static-routes code 121 = array of unsigned integer 8; +- +-send dhcp-client-identifier = hardware; +- +-request subnet-mask, broadcast-address, time-offset, routers, +- domain-name, domain-name-servers, domain-search, host-name, +- root-path, interface-mtu, classless-static-routes, +- netbios-name-servers, netbios-scope, ntp-servers, +- dhcp6.domain-search, dhcp6.fqdn, +- dhcp6.name-servers, dhcp6.sntp-servers; +diff --git a/modules.d/35network-legacy/dhcp-multi.sh b/modules.d/35network-legacy/dhcp-multi.sh +deleted file mode 100755 +index f8104c33..00000000 +--- a/modules.d/35network-legacy/dhcp-multi.sh ++++ /dev/null +@@ -1,133 +0,0 @@ +-#!/bin/sh +-# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +-# ex: ts=8 sw=4 sts=4 et filetype=sh +-# +-PATH=/usr/sbin:/usr/bin:/sbin:/bin +- +-# File to start dhclient requests on different interfaces in parallel +- +-command -v getarg > /dev/null || . /lib/dracut-lib.sh +-. /lib/net-lib.sh +- +-netif=$1 +-do_vlan=$2 +-arg=$3 +- +-# Run dhclient in parallel +-do_dhclient() { +- local _COUNT=0 +- local _timeout +- local _DHCPRETRY +- _timeout=$(getarg rd.net.timeout.dhcp=) +- _DHCPRETRY=$(getargnum 1 1 1000000000 rd.net.dhcp.retry=) +- +- if [ -n "$_timeout" ]; then +- if ! (dhclient --help 2>&1 | grep -q -F -- '--timeout' 2> /dev/null); then +- warn "rd.net.timeout.dhcp has no effect because dhclient does not implement the --timeout option" +- unset _timeout +- fi +- fi +- +- while [ $_COUNT -lt "$_DHCPRETRY" ]; do +- info "Starting dhcp for interface $netif" +- dhclient "$arg" \ +- ${_timeout:+--timeout "$_timeout"} \ +- -q \ +- -1 \ +- -cf /etc/dhclient.conf \ +- -pf /tmp/dhclient."$netif".pid \ +- -lf /tmp/dhclient."$netif".lease \ +- "$netif" & +- wait $! 2> /dev/null +- +- # wait will return the return value of dhclient +- retv=$? +- +- # dhclient and hence wait returned success, 0. +- if [ $retv -eq 0 ]; then +- return 0 +- fi +- +- # If dhclient exited before wait was called, or it was killed by +- # another thread for interface whose DHCP succeeded, then it will not +- # find the process with that pid and return error code 127. In that +- # case we need to check if /tmp/dhclient.$netif.lease exists. If it +- # does, it means dhclient finished executing before wait was called, +- # and it was successful (return 0). If /tmp/dhclient.$netif.lease +- # does not exist, then it means dhclient was killed by another thread +- # or it finished execution but failed dhcp on that interface. +- +- if [ $retv -eq 127 ]; then +- read -r pid < /tmp/dhclient."$netif".pid +- info "PID $pid was not found by wait for $netif" +- if [ -e /tmp/dhclient."$netif".lease ]; then +- info "PID $pid not found but DHCP successful on $netif" +- return 0 +- fi +- fi +- +- _COUNT=$((_COUNT + 1)) +- [ $_COUNT -lt "$_DHCPRETRY" ] && sleep 1 +- done +- warn "dhcp for interface $netif failed" +- # nuke those files since we failed; we might retry dhcp again if it's e.g. +- # `ip=dhcp,dhcp6` and we check for the PID file earlier +- rm -f /tmp/dhclient."$netif".pid /tmp/dhclient."$netif".lease +- return 1 +-} +- +-do_dhclient +-ret=$? +- +-# setup nameserver +-for s in "$dns1" "$dns2" $(getargs nameserver); do +- [ -n "$s" ] || continue +- echo nameserver "$s" >> /tmp/net."$netif".resolv.conf +-done +- +-if [ $ret -eq 0 ]; then +- : > /tmp/net."${netif}".up +- +- if [ -z "$do_vlan" ] && [ -e /sys/class/net/"${netif}"/address ]; then +- : > "/tmp/net.$(cat /sys/class/net/"${netif}"/address).up" +- fi +- +- # Check if DHCP also succeeded on another interface before this one. +- # We will always use the first one on which DHCP succeeded, by using +- # a common file $IFNETFILE, to synchronize between threads. +- # Consider the race condition in which multiple threads +- # corresponding to different interfaces may try to read $IFNETFILE +- # and find it does not exist; they may all end up thinking they are the +- # first to succeed (hence more than one thread may end up writing to +- # $IFNETFILE). To take care of this, instead of checking if $IFNETFILE +- # exists to determine if we are the first, we create a symbolic link +- # in $IFNETFILE, pointing to the interface name ($netif), thus storing +- # the interface name in the link pointer. +- # Creating a link will fail, if the link already exists, hence kernel +- # will take care of allowing only first thread to create link, which +- # takes care of the race condition for us. Subsequent threads will fail. +- # Also, the link points to the interface name, which will tell us which +- # interface succeeded. +- +- if ln -s "$netif" "$IFNETFILE" 2> /dev/null; then +- intf=$(readlink "$IFNETFILE") +- if [ -e /tmp/dhclient."$intf".lease ]; then +- info "DHCP successful on interface $intf" +- # Kill all existing dhclient calls for other interfaces, since we +- # already got one successful interface +- +- read -r npid < /tmp/dhclient."$netif".pid +- pidlist=$(pgrep dhclient) +- for pid in $pidlist; do +- [ "$pid" -eq "$npid" ] && continue +- kill -9 "$pid" > /dev/null 2>&1 +- done +- else +- echo "ERROR! $IFNETFILE exists but /tmp/dhclient.$intf.lease does not exist!!!" +- fi +- else +- info "DHCP success on $netif, and also on $intf" +- exit 0 +- fi +- exit $ret +-fi +diff --git a/modules.d/35network-legacy/ifup.sh b/modules.d/35network-legacy/ifup.sh +deleted file mode 100755 +index 59629f11..00000000 +--- a/modules.d/35network-legacy/ifup.sh ++++ /dev/null +@@ -1,562 +0,0 @@ +-#!/bin/sh +-# +-# We don't need to check for ip= errors here, that is handled by the +-# cmdline parser script +-# +-# without $2 means this is for real netroot case +-# or it is for manually bring up network ie. for kdump scp vmcore +-PATH=/usr/sbin:/usr/bin:/sbin:/bin +- +-command -v getarg > /dev/null || . /lib/dracut-lib.sh +-command -v ip_to_var > /dev/null || . /lib/net-lib.sh +- +-# Huh? No $1? +-[ -z "$1" ] && exit 1 +- +-# $netif reads easier than $1 +-netif=$1 +- +-# loopback is always handled the same way +-if [ "$netif" = "lo" ]; then +- ip link set lo up +- ip addr add 127.0.0.1/8 dev lo +- exit 0 +-fi +- +-do_dhcp_parallel() { +- # dhclient-script will mark the netif up and generate the online +- # event for nfsroot +- # XXX add -V vendor class and option parsing per kernel +- +- [ -e "/tmp/dhclient.$netif.pid" ] && return 0 +- +- if ! iface_has_carrier "$netif"; then +- warn "No carrier detected on interface $netif" +- return 1 +- fi +- +- bootintf=$(readlink "$IFNETFILE") +- if [ -n "$bootintf" ] && [ -e "/tmp/dhclient.${bootintf}.lease" ]; then +- info "DHCP already succeeded for $bootintf, exiting for $netif" +- return 1 +- fi +- +- if [ ! -e /run/NetworkManager/conf.d/10-dracut-dhclient.conf ]; then +- mkdir -p /run/NetworkManager/conf.d +- echo '[main]' > /run/NetworkManager/conf.d/10-dracut-dhclient.conf +- echo 'dhcp=dhclient' >> /run/NetworkManager/conf.d/10-dracut-dhclient.conf +- fi +- +- /sbin/dhcp-multi.sh "$netif" "$DO_VLAN" "$@" & +- return 0 +-} +- +-# Run dhclient +-do_dhcp() { +- # dhclient-script will mark the netif up and generate the online +- # event for nfsroot +- # XXX add -V vendor class and option parsing per kernel +- +- local _COUNT +- local _timeout +- local _DHCPRETRY +- +- _COUNT=0 +- _timeout=$(getarg rd.net.timeout.dhcp=) +- _DHCPRETRY=$(getargnum 1 1 1000000000 rd.net.dhcp.retry=) +- +- [ -e "/tmp/dhclient.${netif}.pid" ] && return 0 +- +- if ! iface_has_carrier "$netif"; then +- warn "No carrier detected on interface $netif" +- return 1 +- fi +- +- if [ -n "$_timeout" ]; then +- if ! (dhclient --help 2>&1 | grep -q -F -- '--timeout' 2> /dev/null); then +- warn "rd.net.timeout.dhcp has no effect because dhclient does not implement the --timeout option" +- unset _timeout +- fi +- fi +- +- if [ ! -e /run/NetworkManager/conf.d/10-dracut-dhclient.conf ]; then +- mkdir -p /run/NetworkManager/conf.d +- echo '[main]' > /run/NetworkManager/conf.d/10-dracut-dhclient.conf +- echo 'dhcp=dhclient' >> /run/NetworkManager/conf.d/10-dracut-dhclient.conf +- fi +- +- while [ "$_COUNT" -lt "$_DHCPRETRY" ]; do +- info "Starting dhcp for interface $netif" +- dhclient "$@" \ +- ${_timeout:+--timeout "$_timeout"} \ +- -q \ +- -1 \ +- -cf /etc/dhclient.conf \ +- -pf "/tmp/dhclient.${netif}.pid" \ +- -lf "/tmp/dhclient.${netif}.lease" \ +- "$netif" \ +- && return 0 +- _COUNT=$((_COUNT + 1)) +- [ "$_COUNT" -lt "$_DHCPRETRY" ] && sleep 1 +- done +- warn "dhcp for interface $netif failed" +- # nuke those files since we failed; we might retry dhcp again if it's e.g. +- # `ip=dhcp,dhcp6` and we check for the PID file at the top +- rm -f /tmp/dhclient."$netif".pid /tmp/dhclient."$netif".lease +- return 1 +-} +- +-load_ipv6() { +- [ -d /proc/sys/net/ipv6 ] && return +- modprobe ipv6 +- i=0 +- while [ ! -d /proc/sys/net/ipv6 ]; do +- i=$((i + 1)) +- [ $i -gt 10 ] && break +- sleep 0.1 +- done +-} +- +-do_ipv6auto() { +- local ret +- load_ipv6 +- echo 0 > /proc/sys/net/ipv6/conf/"${netif}"/forwarding +- echo 1 > /proc/sys/net/ipv6/conf/"${netif}"/accept_ra +- echo 1 > /proc/sys/net/ipv6/conf/"${netif}"/accept_redirects +- linkup "$netif" +- wait_for_ipv6_auto "$netif" +- ret=$? +- +- [ -n "$hostname" ] && echo "echo $hostname > /proc/sys/kernel/hostname" > "/tmp/net.${netif}.hostname" +- +- return "$ret" +-} +- +-do_ipv6link() { +- local ret +- load_ipv6 +- echo 0 > /proc/sys/net/ipv6/conf/"${netif}"/forwarding +- echo 0 > /proc/sys/net/ipv6/conf/"${netif}"/accept_ra +- echo 0 > /proc/sys/net/ipv6/conf/"${netif}"/accept_redirects +- linkup "$netif" +- +- [ -n "$hostname" ] && echo "echo $hostname > /proc/sys/kernel/hostname" > "/tmp/net.${netif}.hostname" +- +- return "$ret" +-} +- +-# Handle static ip configuration +-do_static() { +- strglobin "$ip" '*:*:*' && load_ipv6 +- +- if ! iface_has_carrier "$netif"; then +- warn "No carrier detected on interface $netif" +- return 1 +- elif ! linkup "$netif"; then +- warn "Could not bring interface $netif up!" +- return 1 +- fi +- +- ip route get "$ip" 2> /dev/null | { +- read -r a rest +- if [ "$a" = "local" ]; then +- warn "Not assigning $ip to interface $netif, cause it is already assigned!" +- return 1 +- fi +- return 0 +- } || return 1 +- +- [ -n "$macaddr" ] && ip link set address "$macaddr" dev "$netif" +- [ -n "$mtu" ] && ip link set mtu "$mtu" dev "$netif" +- if strglobin "$ip" '*:*:*'; then +- # note no ip addr flush for ipv6 +- ip addr add "$ip/$mask" ${srv:+peer "$srv"} dev "$netif" +- echo 0 > /proc/sys/net/ipv6/conf/"${netif}"/forwarding +- echo 1 > /proc/sys/net/ipv6/conf/"${netif}"/accept_ra +- echo 1 > /proc/sys/net/ipv6/conf/"${netif}"/accept_redirects +- wait_for_ipv6_dad "$netif" +- else +- if [ -z "$srv" ]; then +- if command -v arping2 > /dev/null; then +- if arping2 -q -C 1 -c 2 -I "$netif" -0 "$ip"; then +- warn "Duplicate address detected for $ip for interface $netif." +- return 1 +- fi +- else +- if ! arping -f -q -D -c 2 -I "$netif" "$ip"; then +- warn "Duplicate address detected for $ip for interface $netif." +- return 1 +- fi +- fi +- fi +- ip addr flush dev "$netif" +- ip addr add "$ip/$mask" ${srv:+peer "$srv"} brd + dev "$netif" +- fi +- +- [ -n "$gw" ] && echo "ip route replace default via '$gw' dev '$netif'" > "/tmp/net.$netif.gw" +- [ -n "$hostname" ] && echo "echo '$hostname' > /proc/sys/kernel/hostname" > "/tmp/net.$netif.hostname" +- +- return 0 +-} +- +-get_vid() { +- case "$1" in +- vlan*) +- echo "${1#vlan}" +- ;; +- *.*) +- echo "${1##*.}" +- ;; +- esac +-} +- +-# check, if we need VLAN's for this interface +-if [ -z "$DO_VLAN_PHY" ] && [ -e "/tmp/vlan.${netif}.phy" ]; then +- unset DO_VLAN +- NO_AUTO_DHCP=yes DO_VLAN_PHY=yes ifup "$netif" +- modprobe -b -q 8021q +- +- for i in /tmp/vlan.*."${netif}"; do +- [ -e "$i" ] || continue +- unset vlanname +- unset phydevice +- # shellcheck disable=SC1090 +- . "$i" +- if [ -n "$vlanname" ]; then +- linkup "$phydevice" +- ip link add dev "$vlanname" link "$phydevice" type vlan id "$(get_vid "$vlanname")" +- ifup "$vlanname" +- fi +- done +- exit 0 +-fi +- +-# Check, if interface is VLAN interface +-if ! [ -e "/tmp/vlan.${netif}.phy" ]; then +- for i in "/tmp/vlan.${netif}".*; do +- [ -e "$i" ] || continue +- export DO_VLAN=yes +- break +- done +-fi +- +-# bridge this interface? +-if [ -z "$NO_BRIDGE_MASTER" ]; then +- for i in /tmp/bridge.*.info; do +- [ -e "$i" ] || continue +- unset bridgeslaves +- unset bridgename +- # shellcheck disable=SC1090 +- . "$i" +- for ethname in $bridgeslaves; do +- [ "$netif" != "$ethname" ] && continue +- +- NO_BRIDGE_MASTER=yes NO_AUTO_DHCP=yes ifup "$ethname" +- linkup "$ethname" +- if [ ! -e "/tmp/bridge.$bridgename.up" ]; then +- ip link add name "$bridgename" type bridge +- echo 0 > "/sys/devices/virtual/net/$bridgename/bridge/forward_delay" +- : > "/tmp/bridge.$bridgename.up" +- fi +- ip link set dev "$ethname" master "$bridgename" +- ifup "$bridgename" +- exit 0 +- done +- done +-fi +- +-# enslave this interface to bond? +-if [ -z "$NO_BOND_MASTER" ]; then +- for i in /tmp/bond.*.info; do +- [ -e "$i" ] || continue +- unset bondslaves +- unset bondname +- # shellcheck disable=SC1090 +- . "$i" +- for testslave in $bondslaves; do +- [ "$netif" != "$testslave" ] && continue +- +- # already setup +- [ -e "/tmp/bond.$bondname.up" ] && exit 0 +- +- # wait for all slaves to show up +- for slave in $bondslaves; do +- # try to create the slave (maybe vlan or bridge) +- NO_BOND_MASTER=yes NO_AUTO_DHCP=yes ifup "$slave" +- +- if ! ip link show dev "$slave" > /dev/null 2>&1; then +- # wait for the last slave to show up +- exit 0 +- fi +- done +- +- modprobe -q -b bonding +- echo "+$bondname" > /sys/class/net/bonding_masters 2> /dev/null +- ip link set "$bondname" down +- +- # Stolen from ifup-eth +- # add the bits to setup driver parameters here +- for arg in $bondoptions; do +- key=${arg%%=*} +- value=${arg##*=} +- # %{value:0:1} is replaced with non-bash specific construct +- if [ "${key}" = "arp_ip_target" ] && [ "${#value}" != "0" ] && [ "+${value%%+*}" != "+" ]; then +- OLDIFS=$IFS +- IFS=',' +- for arp_ip in $value; do +- echo "+$arp_ip" > "/sys/class/net/${bondname}/bonding/$key" +- done +- IFS=$OLDIFS +- else +- echo "$value" > "/sys/class/net/${bondname}/bonding/$key" +- fi +- done +- +- linkup "$bondname" +- +- for slave in $bondslaves; do +- cat "/sys/class/net/$slave/address" > "/tmp/net.${bondname}.${slave}.hwaddr" +- ip link set "$slave" down +- echo "+$slave" > "/sys/class/net/$bondname/bonding/slaves" +- linkup "$slave" +- done +- +- # Set mtu on bond master +- [ -n "$bondmtu" ] && ip link set mtu "$bondmtu" dev "$bondname" +- +- # add the bits to setup the needed post enslavement parameters +- for arg in $bondoptions; do +- key=${arg%%=*} +- value=${arg##*=} +- if [ "${key}" = "primary" ]; then +- echo "$value" > "/sys/class/net/${bondname}/bonding/$key" +- fi +- done +- +- : > "/tmp/bond.$bondname.up" +- +- NO_BOND_MASTER=yes ifup "$bondname" +- exit $? +- done +- done +-fi +- +-if [ -z "$NO_TEAM_MASTER" ]; then +- for i in /tmp/team.*.info; do +- [ -e "$i" ] || continue +- unset teammaster +- unset teamslaves +- # shellcheck disable=SC1090 +- . "$i" +- for testslave in $teamslaves; do +- [ "$netif" != "$testslave" ] && continue +- +- [ -e "/tmp/team.$teammaster.up" ] && exit 0 +- +- # wait for all slaves to show up +- for slave in $teamslaves; do +- # try to create the slave (maybe vlan or bridge) +- NO_TEAM_MASTER=yes NO_AUTO_DHCP=yes ifup "$slave" +- +- if ! ip link show dev "$slave" > /dev/null 2>&1; then +- # wait for the last slave to show up +- exit 0 +- fi +- done +- +- if [ ! -e "/tmp/team.$teammaster.up" ]; then +- # We shall only bring up those _can_ come up +- # in case of some slave is gone in active-backup mode +- working_slaves="" +- for slave in $teamslaves; do +- teamdctl "${teammaster}" port present "${slave}" 2> /dev/null \ +- && continue +- ip link set dev "$slave" up 2> /dev/null +- if wait_for_if_up "$slave"; then +- working_slaves="$working_slaves$slave " +- fi +- done +- # Do not add slaves now +- teamd -d -U -n -N -t "$teammaster" -f "/etc/teamd/${teammaster}.conf" +- for slave in $working_slaves; do +- # team requires the slaves to be down before joining team +- ip link set dev "$slave" down +- ( +- unset TEAM_PORT_CONFIG +- read -r _hwaddr < "/sys/class/net/$slave/address" +- _subchannels=$(iface_get_subchannels "$slave") +- if [ -n "$_hwaddr" ] && [ -e "/etc/sysconfig/network-scripts/mac-${_hwaddr}.conf" ]; then +- # shellcheck disable=SC1090 +- . "/etc/sysconfig/network-scripts/mac-${_hwaddr}.conf" +- elif [ -n "$_subchannels" ] && [ -e "/etc/sysconfig/network-scripts/ccw-${_subchannels}.conf" ]; then +- # shellcheck disable=SC1090 +- . "/etc/sysconfig/network-scripts/ccw-${_subchannels}.conf" +- elif [ -e "/etc/sysconfig/network-scripts/ifcfg-${slave}" ]; then +- # shellcheck disable=SC1090 +- . "/etc/sysconfig/network-scripts/ifcfg-${slave}" +- fi +- +- if [ -n "${TEAM_PORT_CONFIG}" ]; then +- /usr/bin/teamdctl "${teammaster}" port config update "${slave}" "${TEAM_PORT_CONFIG}" +- fi +- ) +- teamdctl "$teammaster" port add "$slave" +- done +- +- ip link set dev "$teammaster" up +- +- : > "/tmp/team.$teammaster.up" +- NO_TEAM_MASTER=yes ifup "$teammaster" +- exit $? +- fi +- done +- done +-fi +- +-# all synthetic interfaces done.. now check if the interface is available +-if ! ip link show dev "$netif" > /dev/null 2>&1; then +- exit 1 +-fi +- +-# disable manual ifup while netroot is set for simplifying our logic +-# in netroot case we prefer netroot to bringup $netif automatically +-[ -n "$2" ] && [ "$2" = "-m" ] && [ -z "$netroot" ] && manualup="$2" +- +-if [ -n "$manualup" ]; then +- : > "/tmp/net.$netif.manualup" +- rm -f "/tmp/net.${netif}.did-setup" +-else +- [ -e "/tmp/net.${netif}.did-setup" ] && exit 0 +- [ -z "$DO_VLAN" ] \ +- && [ -e "/sys/class/net/$netif/address" ] \ +- && [ -e "/tmp/net.$(cat "/sys/class/net/$netif/address").did-setup" ] && exit 0 +-fi +- +-# Specific configuration, spin through the kernel command line +-# looking for ip= lines +-for p in $(getargs ip=); do +- ip_to_var "$p" +- # skip ibft +- [ "$autoconf" = "ibft" ] && continue +- +- case "$dev" in +- ??:??:??:??:??:??) # MAC address +- _dev=$(iface_for_mac "$dev") +- [ -n "$_dev" ] && dev="$_dev" +- ;; +- ??-??-??-??-??-??) # MAC address in BOOTIF form +- _dev=$(iface_for_mac "$(fix_bootif "$dev")") +- [ -n "$_dev" ] && dev="$_dev" +- ;; +- esac +- +- # If this option isn't directed at our interface, skip it +- if [ -n "$dev" ]; then +- if [ "$dev" != "$netif" ]; then +- [ ! -e "/sys/class/net/$dev" ] \ +- && warn "Network interface '$dev' does not exist!" +- continue +- fi +- else +- iface_is_enslaved "$netif" && continue +- fi +- +- # Store config for later use +- for i in ip srv gw mask hostname macaddr mtu dns1 dns2; do +- eval '[ "$'$i'" ] && echo '$i'="$'$i'"' +- done > "/tmp/net.$netif.override" +- +- for autoopt in $(str_replace "$autoconf" "," " "); do +- case $autoopt in +- dhcp | on | any) +- do_dhcp -4 +- ;; +- single-dhcp) +- do_dhcp_parallel -4 +- exit 0 +- ;; +- dhcp6) +- load_ipv6 +- do_dhcp -6 +- ;; +- auto6) +- do_ipv6auto +- ;; +- either6) +- do_ipv6auto || do_dhcp -6 +- ;; +- link6) +- do_ipv6link +- ;; +- *) +- do_static +- ;; +- esac +- done +- ret=$? +- +- # setup nameserver +- for s in "$dns1" "$dns2" $(getargs nameserver); do +- [ -n "$s" ] || continue +- echo "nameserver $s" >> "/tmp/net.$netif.resolv.conf" +- done +- +- if [ $ret -eq 0 ]; then +- : > "/tmp/net.${netif}.up" +- +- if [ -z "$DO_VLAN" ] && [ -e "/sys/class/net/${netif}/address" ]; then +- : > "/tmp/net.$(cat "/sys/class/net/${netif}/address").up" +- fi +- +- # and finally, finish interface set up if there isn't already a script +- # to do so (which is the case in the dhcp path) +- if [ ! -e "$hookdir/initqueue/setup_net_$netif.sh" ]; then +- setup_net "$netif" +- source_hook initqueue/online "$netif" +- if [ -z "$manualup" ]; then +- /sbin/netroot "$netif" +- fi +- fi +- +- exit $ret +- fi +-done +- +-# no ip option directed at our interface? +-if [ -z "$NO_AUTO_DHCP" ] && [ ! -e "/tmp/net.${netif}.up" ]; then +- ret=1 +- if [ -e /tmp/net.bootdev ]; then +- read -r BOOTDEV < /tmp/net.bootdev +- if [ "$netif" = "$BOOTDEV" ] || [ "$BOOTDEV" = "$(cat "/sys/class/net/${netif}/address")" ]; then +- do_dhcp +- ret=$? +- fi +- else +- # No ip lines, no bootdev -> default to dhcp +- ip=$(getarg ip) +- +- if getargs 'ip=dhcp6' > /dev/null || [ -z "$ip" ] && [ "$netroot" = "dhcp6" ]; then +- load_ipv6 +- do_dhcp -6 +- ret=$? +- fi +- if getargs 'ip=dhcp' > /dev/null || [ -z "$ip" ] && [ "$netroot" != "dhcp6" ]; then +- do_dhcp -4 +- ret=$? +- fi +- fi +- +- for s in $(getargs nameserver); do +- [ -n "$s" ] || continue +- echo "nameserver $s" >> "/tmp/net.$netif.resolv.conf" +- done +- +- if [ "$ret" -eq 0 ] && [ -n "$(ls "/tmp/leaseinfo.${netif}"* 2> /dev/null)" ]; then +- : > "/tmp/net.${netif}.did-setup" +- if [ -e "/sys/class/net/${netif}/address" ]; then +- : > "/tmp/net.$(cat "/sys/class/net/${netif}/address").did-setup" +- fi +- fi +-fi +- +-exit 0 +diff --git a/modules.d/35network-legacy/kill-dhclient.sh b/modules.d/35network-legacy/kill-dhclient.sh +deleted file mode 100755 +index 9ed615fd..00000000 +--- a/modules.d/35network-legacy/kill-dhclient.sh ++++ /dev/null +@@ -1,15 +0,0 @@ +-#!/bin/sh +- +-for f in /tmp/dhclient.*.pid; do +- [ -e "$f" ] || continue +- read -r PID < "$f" +- kill "$PID" > /dev/null 2>&1 +-done +- +-sleep 0.1 +- +-for f in /tmp/dhclient.*.pid; do +- [ -e "$f" ] || continue +- read -r PID < "$f" +- kill -9 "$PID" > /dev/null 2>&1 +-done +diff --git a/modules.d/35network-legacy/module-setup.sh b/modules.d/35network-legacy/module-setup.sh +deleted file mode 100755 +index 00e1f36b..00000000 +--- a/modules.d/35network-legacy/module-setup.sh ++++ /dev/null +@@ -1,102 +0,0 @@ +-#!/bin/bash +- +-# called by dracut +-check() { +- require_binaries ip dhclient sed awk grep pgrep tr expr || return 1 +- require_any_binary arping arping2 || return 1 +- +- return 255 +-} +- +-# called by dracut +-depends() { +- echo net-lib kernel-network-modules +- return 0 +-} +- +-# called by dracut +-installkernel() { +- # arping depends on af_packet +- hostonly='' instmods af_packet +-} +- +-# called by dracut +-install() { +- local _arch +- +- # Adding default link and (if exists) 98-default-mac-none.link +- if dracut_module_included "systemd"; then +- inst_multiple -o \ +- "${systemdnetwork}/99-default.link" \ +- "${systemdnetwork}/98-default-mac-none.link" +- [[ $hostonly ]] && inst_multiple -H -o "${systemdnetworkconfdir}/*.link" +- fi +- +- inst_multiple ip dhclient sed awk grep pgrep tr expr +- +- inst_multiple -o arping arping2 +- strstr "$(arping 2>&1)" "ARPing 2" && mv "$initdir/bin/arping" "$initdir/bin/arping2" +- +- inst_multiple -o ping ping6 +- inst_multiple -o teamd teamdctl teamnl +- inst_simple /etc/libnl/classid +- inst_script "$moddir/ifup.sh" "/sbin/ifup" +- inst_script "$moddir/dhcp-multi.sh" "/sbin/dhcp-multi.sh" +- inst_script "$moddir/dhclient-script.sh" "/sbin/dhclient-script" +- inst_simple -H "/etc/dhclient.conf" +- cat "$moddir/dhclient.conf" >> "${initdir}/etc/dhclient.conf" +- inst_hook pre-udev 60 "$moddir/net-genrules.sh" +- inst_hook cmdline 92 "$moddir/parse-ibft.sh" +- inst_hook cmdline 95 "$moddir/parse-vlan.sh" +- inst_hook cmdline 96 "$moddir/parse-bond.sh" +- inst_hook cmdline 96 "$moddir/parse-team.sh" +- inst_hook cmdline 97 "$moddir/parse-bridge.sh" +- inst_hook cmdline 98 "$moddir/parse-ip-opts.sh" +- inst_hook cmdline 99 "$moddir/parse-ifname.sh" +- inst_hook cleanup 10 "$moddir/kill-dhclient.sh" +- +- # install all config files for teaming +- unset TEAM_MASTER +- unset TEAM_CONFIG +- unset TEAM_PORT_CONFIG +- unset HWADDR +- unset SUBCHANNELS +- for i in /etc/sysconfig/network-scripts/ifcfg-*; do +- [ -e "$i" ] || continue +- case "$i" in +- *~ | *.bak | *.orig | *.rpmnew | *.rpmorig | *.rpmsave) +- continue +- ;; +- esac +- ( +- # shellcheck disable=SC1090 +- . "$i" +- if ! [ "${ONBOOT}" = "no" ] || [ "${ONBOOT}" = "NO" ] \ +- && [ -n "${TEAM_MASTER}${TEAM_CONFIG}${TEAM_PORT_CONFIG}" ]; then +- if [ -n "$TEAM_CONFIG" ] && [ -n "$DEVICE" ]; then +- mkdir -p "$initdir"/etc/teamd +- printf -- "%s" "$TEAM_CONFIG" > "$initdir/etc/teamd/${DEVICE}.conf" +- elif [ -n "$TEAM_PORT_CONFIG" ]; then +- inst_simple "$i" +- +- HWADDR="$(echo "$HWADDR" | sed 'y/ABCDEF/abcdef/')" +- if [ -n "$HWADDR" ]; then +- ln_r "$i" "/etc/sysconfig/network-scripts/mac-${HWADDR}.conf" +- fi +- +- SUBCHANNELS="$(echo "$SUBCHANNELS" | sed 'y/ABCDEF/abcdef/')" +- if [ -n "$SUBCHANNELS" ]; then +- ln_r "$i" "/etc/sysconfig/network-scripts/ccw-${SUBCHANNELS}.conf" +- fi +- fi +- fi +- ) +- done +- +- _arch=${DRACUT_ARCH:-$(uname -m)} +- +- inst_libdir_file {"tls/$_arch/",tls/,"$_arch/",}"libnss_dns.so.*" \ +- {"tls/$_arch/",tls/,"$_arch/",}"libnss_mdns4_minimal.so.*" +- +- dracut_need_initqueue +-} +diff --git a/modules.d/35network-legacy/net-genrules.sh b/modules.d/35network-legacy/net-genrules.sh +deleted file mode 100755 +index 686db593..00000000 +--- a/modules.d/35network-legacy/net-genrules.sh ++++ /dev/null +@@ -1,125 +0,0 @@ +-#!/bin/sh +- +-getargbool 0 rd.neednet && NEEDNET=1 +- +-# Don't continue if we don't need network +-if [ -z "$netroot" ] && [ ! -e "/tmp/net.ifaces" ] && [ "$NEEDNET" != "1" ]; then +- return +-fi +- +-command -v fix_bootif > /dev/null || . /lib/net-lib.sh +- +-# Write udev rules +-{ +- # bridge: attempt only the defined interface +- for i in /tmp/bridge.*.info; do +- [ -e "$i" ] || continue +- unset bridgeslaves +- unset bridgename +- # shellcheck disable=SC1090 +- . "$i" +- RAW_IFACES="$RAW_IFACES $bridgeslaves" +- MASTER_IFACES="$MASTER_IFACES $bridgename" +- done +- +- # bond: attempt only the defined interface (override bridge defines) +- for i in /tmp/bond.*.info; do +- [ -e "$i" ] || continue +- unset bondslaves +- unset bondname +- # shellcheck disable=SC1090 +- . "$i" +- # It is enough to fire up only one +- RAW_IFACES="$RAW_IFACES $bondslaves" +- MASTER_IFACES="$MASTER_IFACES ${bondname}" +- done +- +- for i in /tmp/team.*.info; do +- [ -e "$i" ] || continue +- unset teamslaves +- unset teammaster +- # shellcheck disable=SC1090 +- . "$i" +- RAW_IFACES="$RAW_IFACES ${teamslaves}" +- MASTER_IFACES="$MASTER_IFACES ${teammaster}" +- done +- +- for i in /tmp/vlan.*.phy; do +- [ -e "$i" ] || continue +- unset phydevice +- # shellcheck disable=SC1090 +- . "$i" +- RAW_IFACES="$RAW_IFACES $phydevice" +- for j in /tmp/vlan.*".${phydevice}"; do +- [ -e "$j" ] || continue +- unset vlanname +- # shellcheck disable=SC1090 +- . "$j" +- MASTER_IFACES="$MASTER_IFACES ${vlanname}" +- done +- done +- +- MASTER_IFACES="$(trim "$MASTER_IFACES")" +- RAW_IFACES="$(trim "$RAW_IFACES")" +- +- if [ -z "$IFACES" ]; then +- [ -e /tmp/net.ifaces ] && read -r IFACES < /tmp/net.ifaces +- fi +- +- if [ -e /tmp/net.bootdev ]; then +- read -r bootdev < /tmp/net.bootdev +- fi +- +- # shellcheck disable=SC2016 +- ifup='/sbin/ifup $name' +- +- runcmd="RUN+=\"/sbin/initqueue --name ifup-\$name --unique --onetime $ifup\"" +- +- # We have some specific interfaces to handle +- if [ -n "${RAW_IFACES}${IFACES}" ]; then +- echo 'SUBSYSTEM!="net", GOTO="net_end"' +- echo 'ACTION!="add|change|move", GOTO="net_end"' +- for iface in $IFACES $RAW_IFACES; do +- case "$iface" in +- ??:??:??:??:??:??) # MAC address +- cond="ATTR{address}==\"$iface\"" +- echo "$cond, $runcmd, GOTO=\"net_end\"" +- ;; +- ??-??-??-??-??-??) # MAC address in BOOTIF form +- cond="ATTR{address}==\"$(fix_bootif "$iface")\"" +- echo "$cond, $runcmd, GOTO=\"net_end\"" +- ;; +- *) # an interface name +- cond="ENV{INTERFACE}==\"$iface\"" +- echo "$cond, $runcmd, GOTO=\"net_end\"" +- cond="NAME==\"$iface\"" +- echo "$cond, $runcmd, GOTO=\"net_end\"" +- ;; +- esac +- # The GOTO prevents us from trying to ifup the same device twice +- done +- echo 'LABEL="net_end"' +- +- for iface in $IFACES; do +- if [ "$bootdev" = "$iface" ] || [ "$NEEDNET" = "1" ]; then +- if [ -n "$netroot" ] && [ -n "$DRACUT_SYSTEMD" ]; then +- echo "systemctl is-active initrd-root-device.target || [ -f /tmp/net.${iface}.did-setup ]" +- else +- echo "[ -f /tmp/net.${iface}.did-setup ]" +- fi > "$hookdir"/initqueue/finished/wait-"$iface".sh +- fi +- done +- # Default: We don't know the interface to use, handle all +- # Fixme: waiting for the interface as well. +- else +- cond='ACTION=="add", SUBSYSTEM=="net", ENV{DEVTYPE}!="wlan|wwan"' +- # if you change the name of "91-default-net.rules", also change modules.d/80cms/cmssetup.sh +- echo "$cond, $runcmd" > /etc/udev/rules.d/91-default-net.rules +- if [ "$NEEDNET" = "1" ]; then +- # shellcheck disable=SC2016 +- echo 'for i in /tmp/net.*.did-setup; do [ -f "$i" ] && exit 0; done; exit 1' > "$hookdir"/initqueue/finished/wait-network.sh +- fi +- fi +- +- # if you change the name of "90-net.rules", also change modules.d/80cms/cmssetup.sh +-} > /etc/udev/rules.d/90-net.rules +diff --git a/modules.d/35network-legacy/parse-bond.sh b/modules.d/35network-legacy/parse-bond.sh +deleted file mode 100755 +index ba30a3bc..00000000 +--- a/modules.d/35network-legacy/parse-bond.sh ++++ /dev/null +@@ -1,76 +0,0 @@ +-#!/bin/sh +-# +-# Format: +-# bond=[:[:[:]]] +-# +-# bondslaves is a comma-separated list of physical (ethernet) interfaces +-# options is a comma-separated list on bonding options (modinfo bonding for details) in format compatible with initscripts +-# if options include multi-valued arp_ip_target option, then its values should be separated by semicolon. +-# +-# bond without parameters assumes bond=bond0:eth0,eth1:mode=balance-rr +-# +-# if the mtu is specified, it will be set on the bond master +-# +- +-# We translate list of slaves to space-separated here to make it easier to loop over them in ifup +-# Ditto for bonding options +-parsebond() { +- local v="${1}": +- set -- +- while [ -n "$v" ]; do +- set -- "$@" "${v%%:*}" +- v=${v#*:} +- done +- +- case $# in +- 0) +- bondname=bond0 +- bondslaves="eth0 eth1" +- ;; +- 1) +- bondname=$1 +- bondslaves="eth0 eth1" +- ;; +- 2) +- bondname=$1 +- bondslaves=$(str_replace "$2" "," " ") +- ;; +- 3) +- bondname=$1 +- bondslaves=$(str_replace "$2" "," " ") +- bondoptions=$(str_replace "$3" "," " ") +- ;; +- 4) +- bondname=$1 +- bondslaves=$(str_replace "$2" "," " ") +- bondoptions=$(str_replace "$3" "," " ") +- bondmtu=$4 +- ;; +- *) die "bond= requires zero to four parameters" ;; +- esac +-} +- +-# Parse bond for bondname, bondslaves, bondmode, bondoptions and bondmtu +-for bond in $(getargs bond=); do +- unset bondname +- unset bondslaves +- unset bondoptions +- unset bondmtu +- if [ "$bond" != "bond" ]; then +- parsebond "$bond" +- fi +- # Simple default bond +- if [ -z "$bondname" ]; then +- bondname=bond0 +- bondslaves="eth0 eth1" +- fi +- # Make it suitable for initscripts export +- bondoptions=$(str_replace "$bondoptions" ";" ",") +- +- { +- echo "bondname=$bondname" +- echo "bondslaves=\"$bondslaves\"" +- echo "bondoptions=\"$bondoptions\"" +- echo "bondmtu=\"$bondmtu\"" +- } > "/tmp/bond.${bondname}.info" +-done +diff --git a/modules.d/35network-legacy/parse-bridge.sh b/modules.d/35network-legacy/parse-bridge.sh +deleted file mode 100755 +index d331f9d7..00000000 +--- a/modules.d/35network-legacy/parse-bridge.sh ++++ /dev/null +@@ -1,49 +0,0 @@ +-#!/bin/sh +-# +-# Format: +-# bridge=: +-# +-# is a comma-separated list of physical (ethernet) interfaces +-# bridge without parameters assumes bridge=br0:eth0 +-# +- +-parsebridge() { +- local v="${1}": +- set -- +- while [ -n "$v" ]; do +- set -- "$@" "${v%%:*}" +- v=${v#*:} +- done +- case $# in +- 0) +- bridgename=br0 +- bridgeslaves=$iface +- ;; +- 1) die "bridge= requires two parameters" ;; +- 2) +- bridgename=$1 +- bridgeslaves=$(str_replace "$2" "," " ") +- ;; +- *) die "bridge= requires two parameters" ;; +- esac +-} +- +-# Parse bridge for bridgename and bridgeslaves +-for bridge in $(getargs bridge=); do +- unset bridgename +- unset bridgeslaves +- iface=eth0 +- # Read bridge= parameters if they exist +- if [ "$bridge" != "bridge" ]; then +- parsebridge "$bridge" +- fi +- # Simple default bridge +- if [ -z "$bridgename" ]; then +- bridgename=br0 +- bridgeslaves=$iface +- fi +- { +- echo "bridgename=$bridgename" +- echo "bridgeslaves=\"$bridgeslaves\"" +- } > "/tmp/bridge.${bridgename}.info" +-done +diff --git a/modules.d/35network-legacy/parse-ibft.sh b/modules.d/35network-legacy/parse-ibft.sh +deleted file mode 100755 +index 1937f138..00000000 +--- a/modules.d/35network-legacy/parse-ibft.sh ++++ /dev/null +@@ -1,10 +0,0 @@ +-#!/bin/sh +- +-command -v getarg > /dev/null || . /lib/dracut-lib.sh +-command -v ibft_to_cmdline > /dev/null || . /lib/net-lib.sh +- +-if getargbool 0 rd.iscsi.ibft -d "ip=ibft"; then +- modprobe -b -q iscsi_boot_sysfs 2> /dev/null +- modprobe -b -q iscsi_ibft +- ibft_to_cmdline +-fi +diff --git a/modules.d/35network-legacy/parse-ifname.sh b/modules.d/35network-legacy/parse-ifname.sh +deleted file mode 100755 +index be7b6ad6..00000000 +--- a/modules.d/35network-legacy/parse-ifname.sh ++++ /dev/null +@@ -1,24 +0,0 @@ +-#!/bin/sh +-# +-# Format: +-# ifname=: +-# +-# Note letters in the macaddress must be lowercase! +-# +-# Examples: +-# ifname=eth0:4a:3f:4c:04:f8:d7 +-# +-# Note when using ifname= to get persistent interface names, you must specify +-# an ifname= argument for each interface used in an ip= or fcoe= argument +- +-# check if there are any ifname parameters +-if ! getarg ifname= > /dev/null; then +- return +-fi +- +-command -v parse_ifname_opts > /dev/null || . /lib/net-lib.sh +- +-# Check ifname= lines +-for p in $(getargs ifname=); do +- parse_ifname_opts "$p" +-done +diff --git a/modules.d/35network-legacy/parse-ip-opts.sh b/modules.d/35network-legacy/parse-ip-opts.sh +deleted file mode 100755 +index 8263321a..00000000 +--- a/modules.d/35network-legacy/parse-ip-opts.sh ++++ /dev/null +@@ -1,151 +0,0 @@ +-#!/bin/sh +-# +-# Format: +-# ip=[dhcp|on|any|single-dhcp] +-# +-# ip=:[dhcp|on|any][:[][:]] +-# +-# ip=::::::{dhcp|on|any|none|off}[:[][:]] +-# +-# When supplying more than only ip= line, is mandatory and +-# bootdev= must contain the name of the primary interface to use for +-# routing,dns,dhcp-options,etc. +-# +- +-# we really need to use `expr substr` with dash +-# shellcheck disable=SC2003 disable=SC2308 +- +-command -v getarg > /dev/null || . /lib/dracut-lib.sh +- +-if [ -n "$netroot" ] && [ -z "$(getarg ip=)" ] && [ -z "$(getarg BOOTIF=)" ]; then +- # No ip= argument(s) for netroot provided, defaulting to DHCP +- return +-fi +- +-# Count ip= lines to decide whether we need bootdev= or not +-if [ -z "$NEEDBOOTDEV" ]; then +- count=0 +- for p in $(getargs ip=); do +- case "$p" in +- ibft) +- continue +- ;; +- esac +- count=$((count + 1)) +- done +- [ $count -gt 1 ] && NEEDBOOTDEV=1 +-fi +-unset count +- +-# If needed, check if bootdev= contains anything usable +-BOOTDEV=$(getarg bootdev=) +- +-if [ -n "$NEEDBOOTDEV" ] && getargbool 1 rd.neednet; then +- #[ -z "$BOOTDEV" ] && warn "Please supply bootdev argument for multiple ip= lines" +- echo "rd.neednet=1" > /etc/cmdline.d/dracut-neednet.conf +- info "Multiple ip= arguments: assuming rd.neednet=1" +-else +- unset NEEDBOOTDEV +-fi +- +-# Check ip= lines +-# XXX Would be nice if we could errorcheck ip addresses here as well +-for p in $(getargs ip=); do +- ip_to_var "$p" +- +- # make first device specified the BOOTDEV +- if [ -n "$NEEDBOOTDEV" ] && [ -z "$BOOTDEV" ] && [ -n "$dev" ]; then +- BOOTDEV="$dev" +- info "Setting bootdev to '$BOOTDEV'" +- fi +- +- # skip ibft since we did it above +- [ "$autoconf" = "ibft" ] && continue +- +- # Empty autoconf defaults to 'dhcp' +- if [ -z "$autoconf" ]; then +- warn "Empty autoconf values default to dhcp" +- autoconf="dhcp" +- fi +- +- # Error checking for autoconf in combination with other values +- for autoopt in $(str_replace "$autoconf" "," " "); do +- case $autoopt in +- error) die "Error parsing option 'ip=$p'" ;; +- bootp | rarp | both) die "Sorry, ip=$autoopt is currently unsupported" ;; +- none | off) +- [ -z "$ip" ] \ +- && die "For argument 'ip=$p'\nValue '$autoopt' without static configuration does not make sense" +- [ -z "$mask" ] \ +- && die "Sorry, automatic calculation of netmask is not yet supported" +- ;; +- auto6 | link6) ;; +- either6) ;; +- dhcp | dhcp6 | on | any | single-dhcp) +- [ -n "$NEEDBOOTDEV" ] && [ -z "$dev" ] \ +- && die "Sorry, 'ip=$p' does not make sense for multiple interface configurations" +- [ -n "$ip" ] \ +- && die "For argument 'ip=$p'\nSorry, setting client-ip does not make sense for '$autoopt'" +- ;; +- *) die "For argument 'ip=$p'\nSorry, unknown value '$autoopt'" ;; +- esac +- done +- +- if [ -n "$dev" ]; then +- # We don't like duplicate device configs +- if [ -n "$IFACES" ]; then +- for i in $IFACES; do +- [ "$dev" = "$i" ] && die "For argument 'ip=$p'\nDuplication configurations for '$dev'" +- done +- fi +- # IFACES list for later use +- IFACES="$IFACES $dev" +- +- # Interface should exist +- if [ ! -e "/sys/class/net/$dev" ]; then +- warn "Network interface '$dev' does not exist" +- fi +- fi +- +- # Do we need to check for specific options? +- if [ -n "$NEEDDHCP" ] || [ -n "$DHCPORSERVER" ]; then +- # Correct device? (Empty is ok as well) +- [ "$dev" = "$BOOTDEV" ] || continue +- # Server-ip is there? +- [ -n "$DHCPORSERVER" ] && [ -n "$srv" ] && continue +- # dhcp? (It's simpler to check for a set ip. Checks above ensure that if +- # ip is there, we're static +- [ -z "$ip" ] && continue +- # Not good! +- die "Server-ip or dhcp for netboot needed, but current arguments say otherwise" +- fi +- +- if str_starts "$dev" "enx" && [ ${#dev} -eq 15 ]; then +- # shellcheck disable=SC2003 +- printf -- "ifname=%s:%s:%s:%s:%s:%s:%s\n" \ +- "$dev" \ +- "$(expr substr "$dev" 3 2)" \ +- "$(expr substr "$dev" 5 2)" \ +- "$(expr substr "$dev" 7 2)" \ +- "$(expr substr "$dev" 9 2)" \ +- "$(expr substr "$dev" 11 2)" \ +- "$(expr substr "$dev" 13 2)" \ +- >> /etc/cmdline.d/80-enx.conf +- fi +-done +- +-# put BOOTIF in IFACES to make sure it comes up +-if getargbool 1 "rd.bootif" && BOOTIF="$(getarg BOOTIF=)"; then +- BOOTDEV=$(fix_bootif "$BOOTIF") +- IFACES="$BOOTDEV $IFACES" +-fi +- +-# This ensures that BOOTDEV is always first in IFACES +-if [ -n "$BOOTDEV" ] && [ -n "$IFACES" ]; then +- IFACES="${IFACES%"$BOOTDEV"*} ${IFACES#*"$BOOTDEV"}" +- IFACES="$BOOTDEV $IFACES" +-fi +- +-# Store BOOTDEV and IFACES for later use +-[ -n "$BOOTDEV" ] && echo "$BOOTDEV" > /tmp/net.bootdev +-[ -n "$IFACES" ] && echo "$IFACES" > /tmp/net.ifaces +diff --git a/modules.d/35network-legacy/parse-team.sh b/modules.d/35network-legacy/parse-team.sh +deleted file mode 100755 +index 83badc99..00000000 +--- a/modules.d/35network-legacy/parse-team.sh ++++ /dev/null +@@ -1,66 +0,0 @@ +-#!/bin/sh +-# +-# Format: +-# team=:[:] +-# +-# teamslaves is a comma-separated list of physical (ethernet) interfaces +-# teamrunner is the runner type to be used (see teamd.conf(5)); defaults to activebackup +-# +-# team without parameters assumes team=team0:eth0,eth1:activebackup +-# +- +-parseteam() { +- local v="${1}": +- set -- +- while [ -n "$v" ]; do +- set -- "$@" "${v%%:*}" +- v=${v#*:} +- done +- +- case $# in +- 0) +- teammaster=team0 +- teamslaves="eth0 eth1" +- teamrunner="activebackup" +- ;; +- 1) +- teammaster=$1 +- teamslaves="eth0 eth1" +- teamrunner="activebackup" +- ;; +- 2) +- teammaster=$1 +- teamslaves=$(str_replace "$2" "," " ") +- teamrunner="activebackup" +- ;; +- 3) +- teammaster=$1 +- teamslaves=$(str_replace "$2" "," " ") +- teamrunner=$3 +- ;; +- *) die "team= requires zero to three parameters" ;; +- esac +- return 0 +-} +- +-for team in $(getargs team); do +- [ "$team" = "team" ] && continue +- +- unset teammaster +- unset teamslaves +- unset teamrunner +- +- parseteam "$team" || continue +- +- { +- echo "teammaster=$teammaster" +- echo "teamslaves=\"$teamslaves\"" +- echo "teamrunner=\"$teamrunner\"" +- } > /tmp/team."${teammaster}".info +- +- if ! [ -e /etc/teamd/"${teammaster}".conf ]; then +- warn "Team master $teammaster specified, but no /etc/teamd/$teammaster.conf present. Using $teamrunner." +- mkdir -p /etc/teamd +- printf -- "%s" "{\"runner\": {\"name\": \"$teamrunner\"}, \"link_watch\": {\"name\": \"ethtool\"}}" > "/tmp/${teammaster}.conf" +- fi +-done +diff --git a/modules.d/35network-legacy/parse-vlan.sh b/modules.d/35network-legacy/parse-vlan.sh +deleted file mode 100755 +index c23f8331..00000000 +--- a/modules.d/35network-legacy/parse-vlan.sh ++++ /dev/null +@@ -1,37 +0,0 @@ +-#!/bin/sh +-# +-# Format: +-# vlan=: +-# +- +-parsevlan() { +- local v="${1}": +- set -- +- while [ -n "$v" ]; do +- set -- "$@" "${v%%:*}" +- v=${v#*:} +- done +- +- unset vlanname phydevice +- case $# in +- 2) +- vlanname=$1 +- phydevice=$2 +- ;; +- *) die "vlan= requires two parameters" ;; +- esac +-} +- +-for vlan in $(getargs vlan=); do +- unset vlanname +- unset phydevice +- if [ ! "$vlan" = "vlan" ]; then +- parsevlan "$vlan" +- fi +- +- echo "phydevice=\"$phydevice\"" > /tmp/vlan."${phydevice}".phy +- { +- echo "vlanname=\"$vlanname\"" +- echo "phydevice=\"$phydevice\"" +- } > /tmp/vlan."${vlanname}"."${phydevice}" +-done +-- +2.54.0 + diff --git a/0033-fix-iscsi-replace-echo-writes-with-printf-to-prevent.patch b/0033-fix-iscsi-replace-echo-writes-with-printf-to-prevent.patch new file mode 100644 index 0000000..867fe73 --- /dev/null +++ b/0033-fix-iscsi-replace-echo-writes-with-printf-to-prevent.patch @@ -0,0 +1,101 @@ +From b1a90189bfe562ecc57cd3e91c86ac5206b89b99 Mon Sep 17 00:00:00 2001 +From: Pavel Valena +Date: Thu, 7 May 2026 00:45:31 +0200 +Subject: [PATCH 33/34] fix(iscsi): replace `echo` writes with `printf` to + prevent variable injection +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Use printf with explicit variable escaping `%q` for shell scripts: + - mount-lun.sh hookdir script (iscsi_lun variable) + - udev rule (iscsi_lun sanitized via tr -d '"') + - initiatorname.iscsi (sourced as shell at iscsiroot.sh:161-163) + +Note: initiatorname.iscsi is also read by iscsid as plain text (no +shell unquoting). For valid IQNs ([a-z0-9.:_-]), %q is a no-op, so +iscsid sees the value unchanged. For malicious values with special +characters, %q would produce shell escaping that iscsid reads +literally — breaking the connection rather than allowing injection. + +(cherry picked from commit e61fe6afe015744baebfd96411015ae360c1af08) + +Related: RHEL-170844 +--- + modules.d/95iscsi/iscsiroot.sh | 10 +++++----- + modules.d/95iscsi/parse-iscsiroot.sh | 4 ++-- + 2 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/modules.d/95iscsi/iscsiroot.sh b/modules.d/95iscsi/iscsiroot.sh +index d22e958c..1898ef57 100755 +--- a/modules.d/95iscsi/iscsiroot.sh ++++ b/modules.d/95iscsi/iscsiroot.sh +@@ -144,7 +144,7 @@ handle_netroot() { + + if [ -z "$iscsi_initiator" ] && [ -f /sys/firmware/ibft/initiator/initiator-name ] && ! [ -f /tmp/iscsi_set_initiator ]; then + iscsi_initiator=$(while read -r line || [ -n "$line" ]; do echo "$line"; done < /sys/firmware/ibft/initiator/initiator-name) +- echo "InitiatorName=$iscsi_initiator" > /run/initiatorname.iscsi ++ printf 'InitiatorName=%q\n' "$iscsi_initiator" > /run/initiatorname.iscsi + rm -f /etc/iscsi/initiatorname.iscsi + mkdir -p /etc/iscsi + ln -fs /run/initiatorname.iscsi /etc/iscsi/initiatorname.iscsi +@@ -165,7 +165,7 @@ handle_netroot() { + + if [ -z "$iscsi_initiator" ]; then + iscsi_initiator=$(iscsi-iname) +- echo "InitiatorName=$iscsi_initiator" > /run/initiatorname.iscsi ++ printf 'InitiatorName=%q\n' "$iscsi_initiator" > /run/initiatorname.iscsi + rm -f /etc/iscsi/initiatorname.iscsi + mkdir -p /etc/iscsi + ln -fs /run/initiatorname.iscsi /etc/iscsi/initiatorname.iscsi +@@ -189,7 +189,7 @@ handle_netroot() { + iscsi_lun=0 + fi + +- echo "InitiatorName=$iscsi_initiator" > /run/initiatorname.iscsi ++ printf 'InitiatorName=%q\n' "$iscsi_initiator" > /run/initiatorname.iscsi + ln -fs /run/initiatorname.iscsi /dev/.initiatorname.iscsi + if ! [ -e /etc/iscsi/initiatorname.iscsi ]; then + mkdir -p /etc/iscsi +@@ -210,14 +210,14 @@ handle_netroot() { + + if [ "$root" = "dhcp" ] || [ "$netroot" = "dhcp" ]; then + # if root is not specified try to mount the whole iSCSI LUN +- printf 'SYMLINK=="disk/by-path/*-iscsi-*-%s", SYMLINK+="root"\n' "$iscsi_lun" >> /etc/udev/rules.d/99-iscsi-root.rules ++ printf 'SYMLINK=="disk/by-path/*-iscsi-*-%s", SYMLINK+="root"\n' "$(printf '%s' "$iscsi_lun" | tr -d '"')" >> /etc/udev/rules.d/99-iscsi-root.rules + udevadm control --reload + write_fs_tab /dev/root + wait_for_dev -n /dev/root + + # install mount script + [ -z "$DRACUT_SYSTEMD" ] \ +- && echo "iscsi_lun=$iscsi_lun . /bin/mount-lun.sh " > "$hookdir"/mount/01-$$-iscsi.sh ++ && printf 'iscsi_lun=%q . /bin/mount-lun.sh\n' "$iscsi_lun" > "$hookdir"/mount/01-$$-iscsi.sh + fi + + if strglobin "$iscsi_target_ip" '*:*:*' && ! strglobin "$iscsi_target_ip" '['; then +diff --git a/modules.d/95iscsi/parse-iscsiroot.sh b/modules.d/95iscsi/parse-iscsiroot.sh +index a388bec1..d932d4f7 100755 +--- a/modules.d/95iscsi/parse-iscsiroot.sh ++++ b/modules.d/95iscsi/parse-iscsiroot.sh +@@ -111,7 +111,7 @@ fi + + if arg=$(getarg rd.iscsi.initiator -d iscsi_initiator=) && [ -n "$arg" ] && ! [ -f /run/initiatorname.iscsi ]; then + iscsi_initiator=$arg +- echo "InitiatorName=$iscsi_initiator" > /run/initiatorname.iscsi ++ printf 'InitiatorName=%q\n' "$iscsi_initiator" > /run/initiatorname.iscsi + ln -fs /run/initiatorname.iscsi /dev/.initiatorname.iscsi + rm -f /etc/iscsi/initiatorname.iscsi + mkdir -p /etc/iscsi +@@ -127,7 +127,7 @@ fi + if [ -z "$iscsi_initiator" ] && [ -f /sys/firmware/ibft/initiator/initiator-name ] && ! [ -f /tmp/iscsi_set_initiator ]; then + iscsi_initiator=$(while read -r line || [ -n "$line" ]; do echo "$line"; done < /sys/firmware/ibft/initiator/initiator-name) + if [ -n "$iscsi_initiator" ]; then +- echo "InitiatorName=$iscsi_initiator" > /run/initiatorname.iscsi ++ printf 'InitiatorName=%q\n' "$iscsi_initiator" > /run/initiatorname.iscsi + rm -f /etc/iscsi/initiatorname.iscsi + mkdir -p /etc/iscsi + ln -fs /run/initiatorname.iscsi /etc/iscsi/initiatorname.iscsi +-- +2.54.0 + diff --git a/0034-fix-base-escape-arguments-in-initqueue-hook-script-g.patch b/0034-fix-base-escape-arguments-in-initqueue-hook-script-g.patch new file mode 100644 index 0000000..90538c2 --- /dev/null +++ b/0034-fix-base-escape-arguments-in-initqueue-hook-script-g.patch @@ -0,0 +1,73 @@ +From 05c0f8964a5c845348b8a6ce36560194b6cb2729 Mon Sep 17 00:00:00 2001 +From: Pavel Valena +Date: Thu, 14 May 2026 14:20:17 +0200 +Subject: [PATCH 34/36] fix(base): escape arguments in initqueue hook script + generation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +initqueue.sh writes arguments directly into generated hook scripts +via `echo "$exe" "$@"`. These scripts are later sourced by +dracut-initqueue.sh, so shell metacharacters in arguments (e.g. +DHCP-derived $netroot passed from parse-iscsiroot.sh) execute as +root in initramfs. + +Replace `echo` with `printf '%q'` to shell-escape all arguments +before writing them into the hook script, preventing command +injection via DHCP-controlled netroot values. + +Remove the fragile embedded single-quote wrapping ("'$var'") from +parse-iscsiroot.sh call sites (lines 90, 102) — those relied on +echo writing quotes verbatim for the shell to strip when sourcing. +With printf '%q', initqueue now handles escaping centrally, so the +manual wrapping is no longer needed and would cause literal quote +characters to leak into iscsiroot arguments. + +Co-Authored-By: Claude Opus 4.6 + +Related: RHEL-170844 +--- + modules.d/95iscsi/parse-iscsiroot.sh | 4 ++-- + modules.d/99base/initqueue.sh | 3 ++- + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/modules.d/95iscsi/parse-iscsiroot.sh b/modules.d/95iscsi/parse-iscsiroot.sh +index d932d4f7..bfc2270d 100755 +--- a/modules.d/95iscsi/parse-iscsiroot.sh ++++ b/modules.d/95iscsi/parse-iscsiroot.sh +@@ -89,7 +89,7 @@ if [ -n "$iscsi_firmware" ]; then + echo "${DRACUT_SYSTEMD+systemctl is-active initrd-root-device.target || }[ -f '/tmp/iscsistarted-firmware' ]" > "$hookdir"/initqueue/finished/iscsi_started.sh + /sbin/initqueue --unique --online /sbin/iscsiroot online "iscsi:" "$NEWROOT" + /sbin/initqueue --unique --onetime --timeout /sbin/iscsiroot timeout "iscsi:" "$NEWROOT" +- /sbin/initqueue --unique --onetime --settled /sbin/iscsiroot online "iscsi:" "'$NEWROOT'" ++ /sbin/initqueue --unique --onetime --settled /sbin/iscsiroot online "iscsi:" "$NEWROOT" + fi + + # ISCSI actually supported? +@@ -105,7 +105,7 @@ modprobe -b -q be2iscsi + + if [ -n "$netroot" ] && [ "$root" != "/dev/root" ] && [ "$root" != "dhcp" ]; then + if ! getargbool 1 rd.neednet > /dev/null || ! getarg "ip="; then +- /sbin/initqueue --unique --onetime --settled /sbin/iscsiroot dummy "'$netroot'" "'$NEWROOT'" ++ /sbin/initqueue --unique --onetime --settled /sbin/iscsiroot dummy "$netroot" "$NEWROOT" + fi + fi + +diff --git a/modules.d/99base/initqueue.sh b/modules.d/99base/initqueue.sh +index 46a00d2a..1caa5273 100755 +--- a/modules.d/99base/initqueue.sh ++++ b/modules.d/99base/initqueue.sh +@@ -64,7 +64,8 @@ fi + # shellcheck disable=SC2016 + [ -n "$onetime" ] && echo '[ -e "$job" ] && rm -f -- "$job"' + [ -n "$env" ] && echo "$env" +- echo "$exe" "$@" ++ printf '%q ' "$exe" "$@" ++ printf '\n' + } > "/tmp/$$-${job}.sh" + + mv -f "/tmp/$$-${job}.sh" "$hookdir/initqueue${qname}/${job}.sh" +-- +2.54.0 + diff --git a/0035-fix-net-lib-warn-on-suspicious-shell-metacharacters-.patch b/0035-fix-net-lib-warn-on-suspicious-shell-metacharacters-.patch new file mode 100644 index 0000000..e46b96c --- /dev/null +++ b/0035-fix-net-lib-warn-on-suspicious-shell-metacharacters-.patch @@ -0,0 +1,48 @@ +From e73665a2f32fc4bf7ab0d761563a229eb6873ca8 Mon Sep 17 00:00:00 2001 +From: Pavel Valena +Date: Thu, 14 May 2026 14:25:07 +0200 +Subject: [PATCH 35/36] fix(net-lib): warn on suspicious shell metacharacters + in hostname file +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +setup_net() sources /tmp/net.$netif.hostname as shell, which is written +by dhclient-script.sh or ifup.sh. Add a defensive check that warns if +the file contains shell metacharacters ($, `, ;, &, |, () that should +never appear in a legitimate hostname, indicating possible DHCP-based +command injection attempts. + +The file is still sourced for compatibility — the writer-side fix +(printf '%q') already prevents execution of injected content. + +Co-Authored-By: Claude Opus 4.6 + +Related: RHEL-170844 +--- + modules.d/45net-lib/net-lib.sh | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/modules.d/45net-lib/net-lib.sh b/modules.d/45net-lib/net-lib.sh +index dc6be881..a41320ed 100755 +--- a/modules.d/45net-lib/net-lib.sh ++++ b/modules.d/45net-lib/net-lib.sh +@@ -131,8 +131,13 @@ setup_net() { + [ -e "/tmp/net.ifaces" ] && read -r IFACES < /tmp/net.ifaces + [ -z "$IFACES" ] && IFACES="$netif" + # run the scripts written by ifup +- # shellcheck disable=SC1090 +- [ -e /tmp/net."$netif".hostname ] && . /tmp/net."$netif".hostname ++ if [ -e /tmp/net."$netif".hostname ]; then ++ if grep -qE '[$`;&|(]' /tmp/net."$netif".hostname 2>/dev/null; then ++ warn "setup_net $netif: /tmp/net.$netif.hostname contains suspicious shell metacharacters" ++ fi ++ # shellcheck disable=SC1090 ++ . /tmp/net."$netif".hostname ++ fi + # shellcheck disable=SC1090 + [ -e /tmp/net."$netif".override ] && . /tmp/net."$netif".override + # shellcheck disable=SC1090 +-- +2.54.0 + diff --git a/0036-fix-systemd-networkd-escape-DHCP-lease-values-in-dhc.patch b/0036-fix-systemd-networkd-escape-DHCP-lease-values-in-dhc.patch new file mode 100644 index 0000000..cf2ce33 --- /dev/null +++ b/0036-fix-systemd-networkd-escape-DHCP-lease-values-in-dhc.patch @@ -0,0 +1,48 @@ +From db72c0e6336643012ff7a2262f3ae9b9f9b956ca Mon Sep 17 00:00:00 2001 +From: Pavel Valena +Date: Thu, 14 May 2026 16:08:00 +0200 +Subject: [PATCH 36/36] fix(systemd-networkd): escape DHCP lease values in + dhcpopts generation + +networkd-run.sh converts DHCP lease values (ROOT_PATH, NEXT_SERVER) +into shell variable assignments written to /tmp/dhclient..dhcpopts, +which is later sourced by netroot.sh, net-lib.sh, and nfs-lib.sh. The +previous sed-based pipeline wrapped values in single quotes without +escaping embedded single quotes, allowing a rogue DHCP server to inject +arbitrary shell commands via a crafted ROOT_PATH or NEXT_SERVER value. + +Replace the grep|sed pipeline with a while-read loop that uses +printf '%q' to shell-escape values before writing, consistent with how +the NetworkManager equivalent (nm-run.sh) already handles this. + +Co-Authored-By: Claude Opus 4.6 + +Related: RHEL-170844 +--- + modules.d/01systemd-networkd/networkd-run.sh | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +diff --git a/modules.d/01systemd-networkd/networkd-run.sh b/modules.d/01systemd-networkd/networkd-run.sh +index a3ea0f6c..e2a33518 100755 +--- a/modules.d/01systemd-networkd/networkd-run.sh ++++ b/modules.d/01systemd-networkd/networkd-run.sh +@@ -12,10 +12,12 @@ for ifpath in /sys/class/net/*; do + leases_file="/run/systemd/netif/leases/$(cat "$ifpath"/ifindex)" + dhcpopts_file="/tmp/dhclient.${ifname}.dhcpopts" + if [ -r "$leases_file" ]; then +- grep -E "^(NEXT_SERVER|ROOT_PATH)=" "$leases_file" \ +- | sed -e "s/NEXT_SERVER=/new_next_server='/" \ +- -e "s/ROOT_PATH=/new_root_path='/" \ +- -e "s/$/'/" > "$dhcpopts_file" || true ++ while IFS='=' read -r key val; do ++ case "$key" in ++ NEXT_SERVER) printf 'new_next_server=%q\n' "$val" ;; ++ ROOT_PATH) printf 'new_root_path=%q\n' "$val" ;; ++ esac ++ done < "$leases_file" > "$dhcpopts_file" + fi + + source_hook initqueue/online "$ifname" +-- +2.54.0 + diff --git a/dracut.spec b/dracut.spec index d9e494d..81fe34d 100644 --- a/dracut.spec +++ b/dracut.spec @@ -8,7 +8,7 @@ Name: dracut Version: 107 -Release: 4%{?dist} +Release: 7%{?dist} Summary: Initramfs generator using udev @@ -115,6 +115,21 @@ Patch30: 0030-fix-dracut.install-remove-extraneous-quotes-in-dracu.patch # feat(i18n): pull 'drm' or 'simpledrm' module unless excluded # Author: Pavel Valena Patch31: 0031-feat-i18n-pull-drm-or-simpledrm-module-unless-exclud.patch +# fix(network-legacy): remove network-legacy completely from the codebase +# Author: Pavel Valena +Patch32: 0032-fix-network-legacy-remove-network-legacy-completely-.patch +# fix(iscsi): replace `echo` writes with `printf` to prevent variable injection +# Author: Pavel Valena +Patch33: 0033-fix-iscsi-replace-echo-writes-with-printf-to-prevent.patch +# fix(base): escape arguments in initqueue hook script generation +# Author: Pavel Valena +Patch34: 0034-fix-base-escape-arguments-in-initqueue-hook-script-g.patch +# fix(net-lib): warn on suspicious shell metacharacters in hostname file +# Author: Pavel Valena +Patch35: 0035-fix-net-lib-warn-on-suspicious-shell-metacharacters-.patch +# fix(systemd-networkd): escape DHCP lease values in dhcpopts generation +# Author: Pavel Valena +Patch36: 0036-fix-systemd-networkd-escape-DHCP-lease-values-in-dhc.patch # Please use source-git to work with this spec file: # HowTo: https://packit.dev/source-git/work-with-source-git @@ -537,6 +552,20 @@ echo 'dracut_rescue_image="yes"' > $RPM_BUILD_ROOT%{dracutlibdir}/dracut.conf.d/ %{_prefix}/lib/kernel/install.d/51-dracut-rescue.install %changelog +* Wed May 27 2026 Pavel Valena - 107-7 +- build: rebuild without an obsoleted patch + +* Wed May 20 2026 Pavel Valena - 107-6 +- fix(base): escape arguments in initqueue hook script generation +- fix(net-lib): warn on suspicious shell metacharacters in hostname file +- fix(systemd-networkd): escape DHCP lease values in dhcpopts generation + Related: RHEL-170844 + +* Thu May 07 2026 Pavel Valena - 107-5 +- fix(network-legacy): remove network-legacy completely from the codebase +- fix(iscsi): replace `echo` writes with `printf` to prevent variable injection + Resolves: RHEL-170844 + * Fri Jan 30 2026 Pavel Valena - 107-4 - fix(systemd-udevd): handle root=gpt-auto for systemd-v258 - fix(systemd-repart): allow partition format