dracut/SOURCES/0110.patch
2026-06-17 06:25:56 -04:00

186 lines
7.6 KiB
Diff

From 7243b11f71f17d08a6b60024dfab8e3ddf338458 Mon Sep 17 00:00:00 2001
From: Pavel Valena <pvalena@redhat.com>
Date: Thu, 23 Apr 2026 17:20:04 +0200
Subject: [PATCH] fix(network-legacy): replace `echo` writes with `printf` to
prevent injection via DHCP
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
DHCP-provided variables (hostname, gateway) were written with echo into
files later sourced as shell by net-lib.sh — allowing command injection
from a rogue DHCP server.
Use printf with explicit variable escaping `%q` for sourced files:
- .hostname files (DHCP hostname, sourced at net-lib.sh:131)
- .gw files (DHCP routers, sourced at net-lib.sh:140)
- do_static gateway and hostname (kernel cmdline ip= parameter)
Plain text config files (.resolv.conf) are left as echo — they are
read by awk, not sourced as shell, so %q escaping would be incorrect.
Resolves: RHEL-170857
---
modules.d/35network-legacy/dhclient-script.sh | 24 +++++++++++++++-------
modules.d/35network-legacy/ifup.sh | 29 ++++++++++++++++++---------
2 files changed, 36 insertions(+), 17 deletions(-)
diff --git a/modules.d/35network-legacy/dhclient-script.sh b/modules.d/35network-legacy/dhclient-script.sh
index 82fc7e2c..2272c4c0 100755
--- a/modules.d/35network-legacy/dhclient-script.sh
+++ b/modules.d/35network-legacy/dhclient-script.sh
@@ -48,22 +48,24 @@ setup_interface() {
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
+ printf 'ip route add %q dev %q\n' "$gw" "$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
+ printf 'ip route replace default via %q dev %q\n' "$main_gw" "$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
+ printf 'ip route add default via %q dev %q\n' "$g" "$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 "${search}${domain}" ]; then
+ echo "search $search $domain" > /tmp/net."$netif".resolv.conf
+ fi
if [ -n "$namesrv" ]; then
for s in $namesrv; do
echo nameserver "$s"
@@ -72,7 +74,10 @@ setup_interface() {
fi
# Note: hostname can be fqdn OR short hostname, so chop off any
# trailing domain name and explicity add any domain if set.
- [ -n "$hostname" ] && echo "echo ${hostname%.$domain}${domain:+.$domain} > /proc/sys/kernel/hostname" > /tmp/net."$netif".hostname
+ if [ -n "$hostname" ]; then
+ safe_hostname=$(printf '%s' "${hostname%."$domain"}${domain:+.$domain}")
+ printf 'echo %q > /proc/sys/kernel/hostname\n' "$safe_hostname" > /tmp/net."$netif".hostname
+ fi
}
setup_interface6() {
@@ -95,7 +100,9 @@ setup_interface6() {
${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 "${search}${domain}" ]; then
+ echo "search $search $domain" > /tmp/net."$netif".resolv.conf
+ fi
if [ -n "$namesrv" ]; then
for s in $namesrv; do
echo nameserver "$s"
@@ -105,7 +112,10 @@ setup_interface6() {
# Note: hostname can be fqdn OR short hostname, so chop off any
# trailing domain name and explicity add any domain if set.
- [ -n "$hostname" ] && echo "echo ${hostname%.$domain}${domain:+.$domain} > /proc/sys/kernel/hostname" > /tmp/net."$netif".hostname
+ if [ -n "$hostname" ]; then
+ safe_hostname=$(printf '%s' "${hostname%."$domain"}${domain:+.$domain}")
+ printf 'echo %q > /proc/sys/kernel/hostname\n' "$safe_hostname" > /tmp/net."$netif".hostname
+ fi
}
parse_option_121() {
diff --git a/modules.d/35network-legacy/ifup.sh b/modules.d/35network-legacy/ifup.sh
index 0dc9541c..84c53dc4 100755
--- a/modules.d/35network-legacy/ifup.sh
+++ b/modules.d/35network-legacy/ifup.sh
@@ -28,7 +28,7 @@ do_dhcp_parallel() {
# event for nfsroot
# XXX add -V vendor class and option parsing per kernel
- [ -e "/tmp/dhclient.$netif.pid" ] && return 0
+ [ -e "/tmp/dhclient.${netif}.pid" ] && return 0
if ! iface_has_carrier "$netif"; then
warn "No carrier detected on interface $netif"
@@ -121,8 +121,10 @@ do_ipv6auto() {
wait_for_ipv6_auto "$netif"
ret=$?
- [ -n "$hostname" ] && echo "echo $hostname > /proc/sys/kernel/hostname" > "/tmp/net.${netif}.hostname"
-
+ if [ -n "$hostname" ]; then
+ safe_hostname=$(printf '%s' "${hostname}")
+ printf 'echo %q > /proc/sys/kernel/hostname\n' "$safe_hostname" > /tmp/net."$netif".hostname
+ fi
return "$ret"
}
@@ -134,7 +136,10 @@ do_ipv6link() {
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"
+ if [ -n "$hostname" ]; then
+ safe_hostname=$(printf '%s' "${hostname}")
+ printf 'echo %q > /proc/sys/kernel/hostname\n' "$safe_hostname" > /tmp/net."$netif".hostname
+ fi
return "$ret"
}
@@ -187,8 +192,12 @@ do_static() {
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"
+ [ -n "$gw" ] && printf "ip route replace default via %q dev %q\n" "$gw" "$netif" > "/tmp/net.${netif}.gw"
+
+ if [ -n "$hostname" ]; then
+ safe_hostname=$(printf '%s' "${hostname}")
+ printf 'echo %q > /proc/sys/kernel/hostname\n' "$safe_hostname" > /tmp/net."$netif".hostname
+ fi
return 0
}
@@ -417,7 +426,7 @@ fi
[ -n "$2" -a "$2" = "-m" ] && [ -z "$netroot" ] && manualup="$2"
if [ -n "$manualup" ]; then
- : > "/tmp/net.$netif.manualup"
+ : > "/tmp/net.${netif}.manualup"
rm -f "/tmp/net.${netif}.did-setup"
else
[ -e "/tmp/net.${netif}.did-setup" ] && exit 0
@@ -458,7 +467,7 @@ for p in $(getargs ip=); do
# 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"
+ done > "/tmp/net.${netif}.override"
for autoopt in $(str_replace "$autoconf" "," " "); do
case $autoopt in
@@ -492,7 +501,7 @@ for p in $(getargs ip=); do
# setup nameserver
for s in "$dns1" "$dns2" $(getargs nameserver); do
[ -n "$s" ] || continue
- echo "nameserver $s" >> "/tmp/net.$netif.resolv.conf"
+ echo "nameserver $s" >> "/tmp/net.${netif}.resolv.conf"
done
if [ $ret -eq 0 ]; then
@@ -546,7 +555,7 @@ if [ -z "$NO_AUTO_DHCP" ] && [ ! -e "/tmp/net.${netif}.up" ]; then
for s in $(getargs nameserver); do
[ -n "$s" ] || continue
- echo "nameserver $s" >> "/tmp/net.$netif.resolv.conf"
+ echo "nameserver $s" >> "/tmp/net.${netif}.resolv.conf"
done
if [ "$ret" -eq 0 ] && [ -n "$(ls "/tmp/leaseinfo.${netif}"* 2> /dev/null)" ]; then