dracut-060-alt0.1.x86_64 unsafe-tmp-usage-in-scripts fail The test discovered scripts with errors which may be used by a user for damaging important system files. For example if a script uses in its work a temp file which is created in /tmp directory, then every user can create symlinks with the same name (pattern) in this directory in order to destroy or rewrite some system or another user's files. Scripts _must_ _use_ mktemp/tempfile or must use $TMPDIR. mktemp/tempfile is safest. $TMPDIR is safer than /tmp/ because libpam-tmpdir creates a subdirectory of /tmp that is only accessible by that user, and then sets TMPDIR and other variables to that. Hence, it doesn't matter nearly as much if you create a non-random filename, because nobody but you can access it. Found error in /usr/lib/dracut/modules.d/99base/init.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/99base/init.sh # # Copyright 2008-2010, Red Hat, Inc. # Harald Hoyer # Jeremy Katz export -p > /tmp/export.orig NEWROOT="/sysroot" [ -d $NEWROOT ] || mkdir -p -m 0755 $NEWROOT OLDPATH=$PATH -- echo "$line" >> /etc/cmdline.d/99-cmdline-ask.conf done fi if ! getargbool 1 'rd.hostonly'; then [ -f /etc/cmdline.d/99-cmdline-ask.conf ] && mv /etc/cmdline.d/99-cmdline-ask.conf /tmp/99-cmdline-ask.conf remove_hostonly_files [ -f /tmp/99-cmdline-ask.conf ] && mv /tmp/99-cmdline-ask.conf /etc/cmdline.d/99-cmdline-ask.conf fi # run scriptlets to parse the command line make_trace_mem "hook cmdline" '1+:mem' '1+:iomem' '3+:slab' getarg 'rd.break=cmdline' -d 'rdbreak=cmdline' && emergency_shell -n cmdline "Break before cmdline" -- *) unset "$i" ;; esac done . /tmp/export.orig 2> /dev/null || : rm -f -- /tmp/export.orig initargs="" read -r CLINE < /proc/cmdline if getarg init= > /dev/null; then ignoreargs="console BOOT_IMAGE" Found error in /usr/lib/dracut/modules.d/98syslog/rsyslogd-start.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/98syslog/rsyslogd-start.sh set -f for filter in $filters; do echo "${filter} @${server}" done ) #echo "*.* /tmp/syslog" } [ -f /tmp/syslog.type ] && read -r type < /tmp/syslog.type [ -f /tmp/syslog.server ] && read -r server < /tmp/syslog.server [ -f /tmp/syslog.filters ] && read -r filters < /tmp/syslog.filters [ -z "$filters" ] && filters="kern.*" [ -f /tmp/syslog.conf ] && read -r conf < /tmp/syslog.conf [ -z "$conf" ] && conf="/etc/rsyslog.conf" && echo "$conf" > /tmp/syslog.conf if [ "$type" = "rsyslogd" ]; then template=/etc/templates/rsyslog.conf if [ -n "$server" ]; then rsyslog_config "$server" "$template" "$filters" > $conf Found error in /usr/lib/dracut/modules.d/98syslog/parse-syslog-opts.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/98syslog/parse-syslog-opts.sh syslogserver=$(getarg syslog.server -d syslog) syslogfilters=$(getargs syslog.filter -d filter) syslogtype=$(getarg syslog.type -d syslogtype) [ -n "$syslogserver" ] && echo "$syslogserver" > /tmp/syslog.server [ -n "$syslogfilters" ] && echo "$syslogfilters" > /tmp/syslog.filters if [ -n "$syslogtype" ]; then echo "$syslogtype" > /tmp/syslog.type else syslogtype=$(detect_syslog) echo "$syslogtype" > /tmp/syslog.type fi Found error in /usr/lib/dracut/modules.d/95nvmf/parse-nvmf-boot-connections.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/95nvmf/parse-nvmf-boot-connections.sh vlan=$(nbft_run_jq .vlan "$hfi_json") || vlan=0 # treat VLAN zero as "no vlan" [ "$vlan" -ne 0 ] || vlan= [ ! -e /tmp/net."${iface}${vlan:+.$vlan}".has_ibft_config ] || return 0 dhcp=$(nbft_run_jq -r .dhcp_server_ipaddr "$hfi_json") # We need to check $? here as the above is an assignment # shellcheck disable=2181 if [ $? -eq 0 ] && [ "$dhcp" ] && [ "$dhcp" != null ]; then -- echo "ip=$ipaddr::$gateway:$prefix:$hostname:$iface${vlan:+.$vlan}:none${dns1:+:$dns1}${dns2:+:$dns2}" fi if [ "$vlan" ]; then echo "vlan=$iface.$vlan:$iface" echo "$mac" > "/tmp/net.$iface.$vlan.has_ibft_config" else echo "$mac" > "/tmp/net.$iface.has_ibft_config" fi : > /tmp/valid_nbft_entry_found } nbft_parse() { local nbft_json n_nbft all_hfi_json n_hfi local j=0 i -- if [ "$traddr" = "none" ]; then warn "traddr is mandatory for $trtype" return 0 fi if [ "$trtype" = "tcp" ]; then : > /tmp/nvmf_needs_network elif [ "$trtype" = "fc" ]; then if [ "$traddr" = "auto" ]; then rm -f /etc/nvme/discovery.conf /etc/nvme/config.json return 1 fi -- nvmf_hostid=$(getarg rd.nvmf.hostid -d nvmf.hostid=) if [ -n "$nvmf_hostid" ]; then echo "$nvmf_hostid" > /etc/nvme/hostid fi rm -f /tmp/nvmf-fc-auto for d in $(getargs rd.nvmf.discover -d nvmf.discover=); do parse_nvmf_discover "$d" || { : > /tmp/nvmf-fc-auto break } done if [ -e /tmp/nvmf_needs_network ] || [ -e /tmp/valid_nbft_entry_found ]; then echo "rd.neednet=1" > /etc/cmdline.d/nvmf-neednet.conf # netroot is a global variable that is present in all "sourced" scripts # shellcheck disable=SC2034 netroot=nbft rm -f /tmp/nvmf_needs_network fi /sbin/initqueue --settled --onetime --name nvmf-connect-settled /sbin/nvmf-autoconnect.sh settled /sbin/initqueue --timeout --onetime --name nvmf-connect-timeout /sbin/nvmf-autoconnect.sh timeout Found error in /usr/lib/dracut/modules.d/90dmraid/dmraid.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/90dmraid/dmraid.sh type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh devenc=$(str_replace "$1" '/' '\2f') [ -e /tmp/dmraid."$devenc" ] && exit 0 : > /tmp/dmraid."$devenc" DM_RAIDS=$(getargs rd.dm.uuid -d rd_DM_UUID=) if [ -n "$DM_RAIDS" ] || getargbool 0 rd.auto; then # run dmraid if udev has settled Found error in /usr/lib/dracut/modules.d/90crypt/probe-keydev.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/90crypt/probe-keydev.sh info "Probing $real_keydev for $keypath..." test_dev -f "$real_keydev" "$keypath" || exit 1 info "Found $keypath on $real_keydev" echo "$luksdev:$real_keydev:$keypath" >> /tmp/luks.keys Found error in /usr/lib/dracut/modules.d/90crypt/parse-keydev.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/90crypt/parse-keydev.sh fi # A keydev of '/' is treated as the initrd itself if [ "/" = "$keydev" ]; then [ -z "$luksdev" ] && luksdev='*' echo "$luksdev:$keydev:$keypath" >> /tmp/luks.keys continue elif [ -n "$keydev" ]; then udevmatch "$keydev" >&7 || { warn 'keydev incorrect!' continue Found error in /usr/lib/dracut/modules.d/04watchdog/watchdog.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/04watchdog/watchdog.sh #!/bin/sh if [ -e /dev/watchdog ]; then if [ ! -e /tmp/watchdog_timeout ]; then wdctl -s 60 /dev/watchdog > /dev/null 2>&1 : > /tmp/watchdog_timeout fi info "Triggering watchdog" : > /dev/watchdog else modprobe ib700wdt; dracut-live-060-alt0.1.noarch unsafe-tmp-usage-in-scripts fail The test discovered scripts with errors which may be used by a user for damaging important system files. For example if a script uses in its work a temp file which is created in /tmp directory, then every user can create symlinks with the same name (pattern) in this directory in order to destroy or rewrite some system or another user's files. Scripts _must_ _use_ mktemp/tempfile or must use $TMPDIR. mktemp/tempfile is safest. $TMPDIR is safer than /tmp/ because libpam-tmpdir creates a subdirectory of /tmp that is only accessible by that user, and then sets TMPDIR and other variables to that. Hence, it doesn't matter nearly as much if you create a non-random filename, because nobody but you can access it. Found error in /usr/lib/dracut/modules.d/90livenet/parse-livenet.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/90livenet/parse-livenet.sh # live updates updates=$(getarg live.updates=) if [ -n "$updates" ]; then # make sure network comes up even if we're doing a local live device if [ -z "$netroot" ]; then echo > /tmp/net.ifaces fi echo "$updates" > /tmp/liveupdates.info echo '[ -e /tmp/liveupdates.done ]' > "$hookdir"/initqueue/finished/liveupdates.sh fi str_starts "$root" "live:" && liveurl="$root" str_starts "$liveurl" "live:" || return liveurl="${liveurl#live:}" Found error in /usr/lib/dracut/modules.d/90livenet/livenetroot.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/90livenet/livenetroot.sh PATH=/usr/sbin:/usr/bin:/sbin:/bin RETRIES=${RETRIES:-100} SLEEP=${SLEEP:-5} [ -e /tmp/livenet.downloaded ] && exit 0 # args get passed from 40network/netroot netroot="$2" liveurl="${netroot#livenet:}" info "fetching $liveurl" -- sleep "$SLEEP" fi i=$((i + 1)) done > /tmp/livenet.downloaded # TODO: couldn't dmsquash-live-root handle this? if [ "${imgfile##*.}" = "iso" ]; then root=$(losetup -f) losetup "$root" "$imgfile" Found error in /usr/lib/dracut/modules.d/90dmsquash-live-autooverlay/create-overlay.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/90dmsquash-live-autooverlay/create-overlay.sh #!/bin/sh type getarg > /dev/null 2>&1 || . /lib/dracut-lib.sh if getargbool 0 rd.live.debug -n -y rdlivedebug; then exec > /tmp/create-overlay.$$.out exec 2>> /tmp/create-overlay.$$.out set -x fi gatherData() { overlay=$(getarg rd.live.overlay) Found error in /usr/lib/dracut/modules.d/90dmsquash-live/iso-scan.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/90dmsquash-live/iso-scan.sh do_iso_scan() { local _name local dev for dev in /dev/disk/by-uuid/*; do _name=$(dev_unit_name "$dev") [ -e /tmp/isoscan-"${_name}" ] && continue : > /tmp/isoscan-"${_name}" mount -t auto -o ro "$dev" "/run/initramfs/isoscan" || continue if [ -f "/run/initramfs/isoscan/$isofile" ]; then losetup -f "/run/initramfs/isoscan/$isofile" udevadm trigger --action=add > /dev/null 2>&1 ln -s "$dev" /run/initramfs/isoscandev Found error in /usr/lib/dracut/modules.d/90dmsquash-live/dmsquash-live-root.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/90dmsquash-live/dmsquash-live-root.sh command -v unpack_archive > /dev/null || . /lib/img-lib.sh PATH=/usr/sbin:/usr/bin:/sbin:/bin if getargbool 0 rd.live.debug -n -y rdlivedebug; then exec > /tmp/liveroot.$$.out exec 2>> /tmp/liveroot.$$.out set -x fi [ -z "$1" ] && exit 1 livedev="$1"; dracut-network-060-alt0.1.noarch unsafe-tmp-usage-in-scripts fail The test discovered scripts with errors which may be used by a user for damaging important system files. For example if a script uses in its work a temp file which is created in /tmp directory, then every user can create symlinks with the same name (pattern) in this directory in order to destroy or rewrite some system or another user's files. Scripts _must_ _use_ mktemp/tempfile or must use $TMPDIR. mktemp/tempfile is safest. $TMPDIR is safer than /tmp/ because libpam-tmpdir creates a subdirectory of /tmp that is only accessible by that user, and then sets TMPDIR and other variables to that. Hence, it doesn't matter nearly as much if you create a non-random filename, because nobody but you can access it. Found error in /usr/lib/dracut/modules.d/95iscsi/parse-iscsiroot.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/95iscsi/parse-iscsiroot.sh [ -z "$netroot" ] && netroot=iscsi: fi modprobe -b -q iscsi_boot_sysfs 2> /dev/null modprobe -b -q iscsi_ibft # if no ip= is given, but firmware echo "${DRACUT_SYSTEMD+systemctl is-active initrd-root-device.target || }[ -f '/tmp/iscsistarted-firmware' ]" > "$hookdir"/initqueue/finished/iscsi_started.sh initqueue --unique --online /sbin/iscsiroot online "iscsi:" "$NEWROOT" initqueue --unique --onetime --timeout /sbin/iscsiroot timeout "iscsi:" "$NEWROOT" initqueue --unique --onetime --settled /sbin/iscsiroot online "iscsi:" "'$NEWROOT'" fi -- sleep 1 fi fi # If not given on the cmdline and initiator-name available via iBFT 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 rm -f /etc/iscsi/initiatorname.iscsi mkdir -p /etc/iscsi ln -fs /run/initiatorname.iscsi /etc/iscsi/initiatorname.iscsi : > /tmp/iscsi_set_initiator if [ -n "$DRACUT_SYSTEMD" ]; then systemctl try-restart iscsid # FIXME: iscsid is not yet ready, when the service is :-/ sleep 1 fi -- for nroot in $(getargs netroot); do [ "${nroot%%:*}" = "iscsi" ] || continue type parse_iscsi_root > /dev/null 2>&1 || . /lib/net-lib.sh parse_iscsi_root "$nroot" || return 1 netroot_enc=$(str_replace "$nroot" '/' '\2f') echo "${DRACUT_SYSTEMD+systemctl is-active initrd-root-device.target || }[ -f '/tmp/iscsistarted-$netroot_enc' ]" > "$hookdir"/initqueue/finished/iscsi_started.sh done # Done, all good! # shellcheck disable=SC2034 rootok=1 Found error in /usr/lib/dracut/modules.d/95iscsi/iscsiroot.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/95iscsi/iscsiroot.sh modprobe crc32c 2> /dev/null # start iscsiuio if needed if [ -z "${DRACUT_SYSTEMD}" ] \ && { [ -e /sys/module/bnx2i ] || [ -e /sys/module/qedi ]; } \ && ! [ -e /tmp/iscsiuio-started ]; then iscsiuio : > /tmp/iscsiuio-started fi handle_firmware() { local ifaces retry _res -- else ifaces=$( set -- /sys/firmware/ibft/ethernet* echo $# ) read -r retry < /tmp/session-retry if [ "$retry" -lt "$ifaces" ]; then retry=$((retry + 1)) echo $retry > /tmp/session-retry return 1 else rm /tmp/session-retry fi # check to see if we have the new iscsiadm command, # that supports the "no-wait" (-W) flag. If so, use it. iscsiadm -m fw -l -W 2> /dev/null -- else need_shutdown fi fi [ -d /sys/class/iscsi_session ] || return 1 echo 'started' > "/tmp/iscsistarted-iscsi:" echo 'started' > "/tmp/iscsistarted-firmware" return 0 } handle_netroot() { -- # XXX is this needed? getarg ro && iscsirw=ro getarg rw && iscsirw=rw fsopts=${fsopts:+$fsopts,}${iscsirw} 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 rm -f /etc/iscsi/initiatorname.iscsi mkdir -p /etc/iscsi ln -fs /run/initiatorname.iscsi /etc/iscsi/initiatorname.iscsi : > /tmp/iscsi_set_initiator if [ -n "$DRACUT_SYSTEMD" ]; then systemctl try-restart iscsid # FIXME: iscsid is not yet ready, when the service is :-/ sleep 1 fi -- iscsi_initiator=$(iscsi-iname) echo "InitiatorName=$iscsi_initiator" > /run/initiatorname.iscsi rm -f /etc/iscsi/initiatorname.iscsi mkdir -p /etc/iscsi ln -fs /run/initiatorname.iscsi /etc/iscsi/initiatorname.iscsi : > /tmp/iscsi_set_initiator if [ -n "$DRACUT_SYSTEMD" ]; then systemctl try-restart iscsid # FIXME: iscsid is not yet ready, when the service is :-/ sleep 1 fi -- return 1 fi : > "$hookdir"/initqueue/work netroot_enc=$(str_replace "$1" '/' '\2f') echo 'started' > "/tmp/iscsistarted-iscsi:${netroot_enc}" return 0 } ret=0 -- sleep 2 fi if getargbool 0 rd.iscsi.firmware -d -y iscsi_firmware; then if [ "$netif" = "timeout" ] || [ "$netif" = "online" ] || [ "$netif" = "dummy" ]; then [ -f /tmp/session-retry ] || echo 1 > /tmp/session-retry handle_firmware ret=$? fi fi Found error in /usr/lib/dracut/modules.d/45ifcfg/write-ifcfg.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/45ifcfg/write-ifcfg.sh #!/bin/sh # NFS root might have reached here before /tmp/net.ifaces was written type is_persistent_ethernet_name > /dev/null 2>&1 || . /lib/net-lib.sh udevadm settle --timeout=30 # shellcheck disable=SC2174 mkdir -m 0755 -p /tmp/ifcfg/ # shellcheck disable=SC2174 mkdir -m 0755 -p /tmp/ifcfg-leases/ get_config_line_by_subchannel() { local CHANNELS local line -- fi echo "DEVICE=\"$_netif\"" } for netup in /tmp/net.*.did-setup; do [ -f "$netup" ] || continue netif=${netup%%.did-setup} netif=${netif##*/net.} strglobin "$netif" ":*:*:*:*:" && continue [ -e /tmp/ifcfg/ifcfg-"$netif" ] && continue unset bridge unset bond unset bondslaves unset bondname unset bondoptions -- unset vlan unset vlanname unset phydevice # shellcheck disable=SC1090 [ -e /tmp/bond."${netif}".info ] && . /tmp/bond."${netif}".info # shellcheck disable=SC1090 [ -e /tmp/bridge."${netif}".info ] && . /tmp/bridge."${netif}".info # shellcheck disable=SC1090 [ -e /tmp/team."${netif}".info ] && . /tmp/team."${netif}".info read -r uuid < /proc/sys/kernel/random/uuid if [ "$netif" = "$bridgename" ]; then bridge=yes elif [ "$netif" = "$teammaster" ]; then -- elif [ "$netif" = "$bondname" ]; then # $netif can't be bridge and bond at the same time bond=yes fi for i in "/tmp/vlan.${netif}."*; do [ ! -e "$i" ] && continue # shellcheck disable=SC1090 . "$i" vlan=yes break -- [ -z "$vlan" ] && interface_bind "$netif" "$macaddr" echo "ONBOOT=yes" echo "NETBOOT=yes" echo "UUID=\"$uuid\"" strstr "$(ip -6 addr show dev "$netif")" 'inet6' && echo "IPV6INIT=yes" if [ -f /tmp/dhclient."$netif".lease ]; then # shellcheck disable=SC1090 [ -f /tmp/dhclient."$netif".dhcpopts ] && . /tmp/dhclient."$netif".dhcpopts if [ -f /tmp/net."$netif".has_ibft_config ]; then echo "BOOTPROTO=ibft" else echo "BOOTPROTO=dhcp" fi cp /tmp/dhclient."$netif".lease /tmp/ifcfg-leases/dhclient-"$uuid"-"$netif".lease else # If we've booted with static ip= lines, the override file is there # shellcheck disable=SC1090 [ -e /tmp/net."$netif".override ] && . /tmp/net."$netif".override if strglobin "$ip" '*:*:*'; then echo "IPV6INIT=yes" echo "IPV6_AUTOCONF=no" echo "IPV6ADDR=\"$ip/$mask\"" else if [ -f /tmp/net."$netif".has_ibft_config ]; then echo "BOOTPROTO=ibft" else echo "BOOTPROTO=none" echo "IPADDR=\"$ip\"" if strstr "$mask" "."; then -- elif [ -n "$gw" ]; then echo "GATEWAY=\"$gw\"" fi fi [ -n "$mtu" ] && echo "MTU=\"$mtu\"" } > /tmp/ifcfg/ifcfg-"$netif" # bridge needs different things written to ifcfg if [ -z "$bridge" ] && [ -z "$bond" ] && [ -z "$vlan" ] && [ -z "$team" ]; then # standard interface echo "TYPE=Ethernet" >> /tmp/ifcfg/ifcfg-"$netif" fi if [ -n "$vlan" ]; then { echo "TYPE=Vlan" echo "DEVICE=\"$netif\"" echo "VLAN=yes" echo "PHYSDEV=\"$phydevice\"" } >> /tmp/ifcfg/ifcfg-"$netif" fi if [ -n "$bond" ]; then # bond interface { # This variable is an indicator of a bond interface for initscripts echo "BONDING_OPTS=\"$bondoptions\"" echo "NAME=\"$netif\"" echo "TYPE=Bond" } >> /tmp/ifcfg/ifcfg-"$netif" for slave in $bondslaves; do # write separate ifcfg file for the raw eth interface ( echo "# Generated by dracut initrd" -- echo "SLAVE=yes" echo "MASTER=\"$netif\"" echo "UUID=\"$(cat /proc/sys/kernel/random/uuid)\"" unset macaddr # shellcheck disable=SC1090 [ -e /tmp/net."$slave".override ] && . /tmp/net."$slave".override interface_bind "$slave" "$macaddr" ) >> /tmp/ifcfg/ifcfg-"$slave" done fi if [ -n "$bridge" ]; then # bridge { echo "TYPE=Bridge" echo "NAME=\"$netif\"" } >> /tmp/ifcfg/ifcfg-"$netif" for slave in $bridgeslaves; do # write separate ifcfg file for the raw eth interface ( echo "# Generated by dracut initrd" echo "NAME=\"$slave\"" -- echo "NETBOOT=yes" echo "BRIDGE=\"$bridgename\"" echo "UUID=\"$(cat /proc/sys/kernel/random/uuid)\"" unset macaddr # shellcheck disable=SC1090 [ -e /tmp/net."$slave".override ] && . /tmp/net."$slave".override interface_bind "$slave" "$macaddr" ) >> /tmp/ifcfg/ifcfg-"$slave" done fi i=1 for ns in $(getargs nameserver) $dns1 $dns2; do echo "DNS${i}=\"${ns}\"" >> /tmp/ifcfg/ifcfg-"$netif" i=$((i + 1)) done [ -f /tmp/net.route6."$netif" ] && cp /tmp/net.route6."$netif" /tmp/ifcfg/route6-"$netif" [ -f /tmp/net.route."$netif" ] && cp /tmp/net.route."$netif" /tmp/ifcfg/route-"$netif" done # Pass network opts mkdir -m 0755 -p /run/initramfs/state/etc/sysconfig/network-scripts mkdir -m 0755 -p /run/initramfs/state/var/lib/dhclient echo "files /etc/sysconfig/network-scripts" >> /run/initramfs/rwtab echo "files /var/lib/dhclient" >> /run/initramfs/rwtab { cp /tmp/net.* /run/initramfs/ for i in /tmp/net.*.resolv.conf; do [ -f "$i" ] && cat "$i" done | awk '!($0 in a) { a[$0]; print }' > /run/initramfs/state/etc/resolv.conf [ -s /run/initramfs/state/etc/resolv.conf ] || rm -f /run/initramfs/state/etc/resolv.conf copytree /tmp/ifcfg /run/initramfs/state/etc/sysconfig/network-scripts cp /tmp/ifcfg-leases/* /run/initramfs/state/var/lib/dhclient } > /dev/null 2>&1 Found error in /usr/lib/dracut/modules.d/40network/net-lib.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/40network/net-lib.sh #!/bin/sh # shellcheck disable=SC2034 IFNETFILE="/tmp/bootnetif" is_ip() { echo "$1" | { IFS=. read -r a b c d test "$a" -ge 0 -a "$a" -le 255 \ -- } # list the configured interfaces configured_ifaces() { local IFACES="" iface_id="" rv=1 [ -e "/tmp/net.ifaces" ] && read -r IFACES < /tmp/net.ifaces if { pidof udevd || pidof systemd-udevd; } > /dev/null; then for iface_id in $IFACES; do printf "%s\n" "$(iface_name "$iface_id")" rv=0 done -- return $rv } all_ifaces_up() { local iface="" IFACES="" [ -e "/tmp/net.ifaces" ] && read -r IFACES < /tmp/net.ifaces for iface in $IFACES; do [ -e /tmp/net."$iface".up ] || return 1 done } all_ifaces_setup() { local iface="" IFACES="" [ -e "/tmp/net.ifaces" ] && read -r IFACES < /tmp/net.ifaces for iface in $IFACES; do [ -e /tmp/net."$iface".did-setup ] || return 1 done } get_netroot_ip() { local prefix="" server="" rest="" -- local netif="$1" # ip down/flush ensures that routing info goes away as well ip link set "$netif" down ip addr flush dev "$netif" echo "#empty" > /etc/resolv.conf rm -f -- /tmp/net."$netif".did-setup [ -z "$DO_VLAN" ] \ && [ -e /sys/class/net/"$netif"/address ] \ && rm -f -- "/tmp/net.$(cat /sys/class/net/"$netif"/address).did-setup" # TODO: send "offline" uevent? } setup_net() { local netif="$1" f="" gw_ip="" netroot_ip="" iface="" IFACES="" local _p [ -e /tmp/net."$netif".did-setup ] && return [ -z "$DO_VLAN" ] \ && [ -e /sys/class/net/"$netif"/address ] \ && [ -e "/tmp/net.$(cat /sys/class/net/"$netif"/address).did-setup" ] && return [ -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 # shellcheck disable=SC1090 [ -e /tmp/net."$netif".override ] && . /tmp/net."$netif".override # shellcheck disable=SC1090 [ -e /tmp/dhclient."$netif".dhcpopts ] && . /tmp/dhclient."$netif".dhcpopts # set up resolv.conf [ -e /tmp/net."$netif".resolv.conf ] \ && awk '!array[$0]++' /tmp/net."$netif".resolv.conf > /etc/resolv.conf # shellcheck disable=SC1090 [ -e /tmp/net."$netif".gw ] && . /tmp/net."$netif".gw # add static route for _p in $(getargs rd.route); do route_to_var "$_p" || continue [ -n "$route_dev" ] && [ "$route_dev" != "$netif" ] && continue ip route add "$route_mask" ${route_gw:+via $route_gw} ${route_dev:+dev $route_dev} if strstr "$route_mask" ":"; then printf -- "%s\n" "$route_mask ${route_gw:+via $route_gw} ${route_dev:+dev $route_dev}" \ > /tmp/net.route6."$netif" else printf -- "%s\n" "$route_mask ${route_gw:+via $route_gw} ${route_dev:+dev $route_dev}" \ > /tmp/net.route."$netif" fi done # If a static route was necessary to reach the gateway, the # first gateway setup call will have failed with # RTNETLINK answers: Network is unreachable # Replace the default route again after static routes to cover # this scenario. # shellcheck disable=SC1090 [ -e /tmp/net."$netif".gw ] && . /tmp/net."$netif".gw # Handle STP Timeout: arping the default gateway. # (or the root server, if a) it's local or b) there's no gateway.) # Note: This assumes that if no router is present the # root server is on the same subnet. -- arping -q -f -w 60 -I "$netif" "$dest" || info "Resolving $dest via ARP on $netif failed" fi fi unset layer2 : > /tmp/net."$netif".did-setup [ -z "$DO_VLAN" ] \ && [ -e /sys/class/net/"$netif"/address ] \ && : > "/tmp/net.$(cat /sys/class/net/"$netif"/address).did-setup" } save_netinfo() { local netif="$1" IFACES="" f="" i="" [ -e /tmp/net.ifaces ] && read -r IFACES < /tmp/net.ifaces # Add $netif to the front of IFACES (if it's not there already). set -- "$netif" for i in $IFACES; do [ "$i" != "$netif" ] && set -- "$@" "$i"; done IFACES="$*" for i in $IFACES; do for f in "/tmp/dhclient.$i."*; do [ -f "$f" ] && cp -f "$f" /tmp/net."${f#/tmp/dhclient.}" done done echo "$IFACES" > /tmp/.net.ifaces.new mv /tmp/.net.ifaces.new /tmp/net.ifaces } set_ifname() { local name="$1" mac="$2" num=-1 n="" # if it's already set, return the existing name for n in $(getargs ifname=); do strstr "$n" "$mac" && echo "${n%%:*}" && return done [ ! -f "/tmp/set_ifname_$name" ] || read -r num < "/tmp/set_ifname_$name" # otherwise, pick a new name and use that while :; do num=$((num + 1)) [ -e /sys/class/net/"$name"$num ] && continue for n in $(getargs ifname=); do [ "$name$num" = "${n%%:*}" ] && continue 2 done break done echo "ifname=$name$num:$mac" >> /etc/cmdline.d/45-ifname.conf echo "$num" > "/tmp/set_ifname_$name" echo "$name$num" } # pxelinux provides macaddr '-' separated, but we need ':' fix_bootif() { -- [ -e "${iface}"/mac ] || continue read -r mac < "${iface}"/mac [ -z "$mac" ] && continue dev=$(set_ifname ibft "$mac") [ -e /tmp/net."${dev}".has_ibft_config ] && continue [ -e "${iface}"/flags ] && read -r flags < "${iface}"/flags # Skip invalid interfaces awk -- 'BEGIN { exit (!and('"$flags"',1)) }' || continue # Skip interfaces not used for booting unless using multipath -- read -r vlan < "${iface}"/vlan if [ "$vlan" -ne "0" ]; then case "$vlan" in [0-9]*) echo "vlan=$dev.$vlan:$dev" echo "$mac" > /tmp/net."${dev}"."${vlan}".has_ibft_config ;; *) echo "vlan=$vlan:$dev" echo "$mac" > /tmp/net."${vlan}".has_ibft_config ;; esac else echo "$mac" > /tmp/net."${dev}".has_ibft_config fi else echo "$mac" > /tmp/net."${dev}".has_ibft_config fi done ) >> /etc/cmdline.d/40-ibft.conf } Found error in /usr/lib/dracut/modules.d/40network/ifname-genrules.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/40network/ifname-genrules.sh { for p in $(getargs ifname=); do parse_ifname_opts "$p" if [ -f /tmp/ifname-"$ifname_mac" ]; then read -r oldif < /tmp/ifname-"$ifname_mac" fi if [ -f /tmp/ifname-"$ifname_if" ]; then read -r oldmac < /tmp/ifname-"$ifname_if" fi if [ -n "$oldif" -a -n "$oldmac" -a "$oldif" = "$ifname_if" -a "$oldmac" = "$ifname_mac" ]; then # skip same ifname= declaration continue fi [ -n "$oldif" ] && warn "Multiple interface names specified for MAC $ifname_mac: $oldif" [ -n "$oldmac" ] && warn "Multiple MAC specified for $ifname_if: $oldmac" printf 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="%s", ATTR{type}=="1", NAME="%s"\n' "$ifname_mac" "$ifname_if" echo "$ifname_if" > /tmp/ifname-"$ifname_mac" echo "$ifname_mac" > /tmp/ifname-"$ifname_if" done } >> /etc/udev/rules.d/80-ifname.rules Found error in /usr/lib/dracut/modules.d/35network-legacy/parse-vlan.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/35network-legacy/parse-vlan.sh 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 Found error in /usr/lib/dracut/modules.d/35network-legacy/parse-team.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/35network-legacy/parse-team.sh { 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 Found error in /usr/lib/dracut/modules.d/35network-legacy/parse-ip-opts.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/35network-legacy/parse-ip-opts.sh 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 Found error in /usr/lib/dracut/modules.d/35network-legacy/parse-bridge.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/35network-legacy/parse-bridge.sh bridgeslaves=$iface fi { echo "bridgename=$bridgename" echo "bridgeslaves=\"$bridgeslaves\"" } > /tmp/bridge.${bridgename}.info done Found error in /usr/lib/dracut/modules.d/35network-legacy/dhcp-multi.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/35network-legacy/dhcp-multi.sh 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=$? -- 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 -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. -- # 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 Found error in /usr/lib/dracut/modules.d/35network-legacy/dhclient-script.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/35network-legacy/dhclient-script.sh [ -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, -- ${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 -- [ -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" -- 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 -- 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) -- 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 Found error in /usr/lib/dracut/modules.d/35connman/cm-run.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/35connman/cm-run.sh #!/bin/bash type source_hook > /dev/null 2>&1 || . /lib/dracut-lib.sh if [ -e /tmp/cm.done ]; then return fi while read -r _serv; do ifname=$(connmanctl services "$_serv" | grep Interface= | sed 's/^.*Interface=\([^,]*\).*$/\1/') source_hook initqueue/online "$ifname" /sbin/netroot "$ifname" done < <(connmanctl services | grep -oE '[^ ]+$') : > /tmp/cm.done; dracut-network-manager-060-alt0.1.noarch unsafe-tmp-usage-in-scripts fail The test discovered scripts with errors which may be used by a user for damaging important system files. For example if a script uses in its work a temp file which is created in /tmp directory, then every user can create symlinks with the same name (pattern) in this directory in order to destroy or rewrite some system or another user's files. Scripts _must_ _use_ mktemp/tempfile or must use $TMPDIR. mktemp/tempfile is safest. $TMPDIR is safer than /tmp/ because libpam-tmpdir creates a subdirectory of /tmp that is only accessible by that user, and then sets TMPDIR and other variables to that. Hence, it doesn't matter nearly as much if you create a non-random filename, because nobody but you can access it. Found error in /usr/lib/dracut/modules.d/35network-manager/nm-run.sh: $ grep -A5 -B5 /tmp/ /usr/lib/dracut/modules.d/35network-manager/nm-run.sh for _i in /sys/class/net/*; do [ -d "$_i" ] || continue state="/run/NetworkManager/devices/$(cat "$_i"/ifindex)" grep -q '^connection-uuid=' "$state" 2> /dev/null || continue ifname="${_i##*/}" dhcpopts_create "$state" > /tmp/dhclient."$ifname".dhcpopts source_hook initqueue/online "$ifname" /sbin/netroot "$ifname" done : > /tmp/nm.done;