[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#816513: Call to configure_network in initramfs script broken due to set -e



Package: mandos-client
Version: 1.6.9-1


Hi,


The mandos initramfs script <${INITRAMFS}/scripts/init-premount/mandos>
is configured with set -e. (#!/bin/sh -e in the shebang).

This causes that it aborts when any command executed returns non-zero and
the return value is not checked.

The problem is that this script sources /scripts/functions from the initramfs
and /scripts/functions was not designed to work with set -e. So when the mandos
script calls any function sourced from /scripts/functions problems may happen.

For example, I have found that when executing the function configure_networking
it will cause the mandos script to abort if the DHCP server don't replies in
less than 2 seconds.

This function is called from the mandos initramfs script
<${INITRAMFS}/scripts/init-premount/mandos> to configure the network
when mandos=connect is specified on the kernel command line.


Let's take a look to the function configure_networking:



configure_networking()
{

# [... skipped code for clarity ....]

	for ROUNDTTT in 2 3 4 6 9 16 25 36 64 100; do

		# The NIC is to be configured if this file does not exist.
		# Ip-Config tries to create this file and when it succeds
		# creating the file, ipconfig is not run again.
		for x in /run/net-"${DEVICE}".conf /run/net-*.conf ; do
			[ -e "$x" ] && break 2
		done

		case ${IP} in
		none|off)
			# Do nothing
			;;
		""|on|any)
			# Bring up device
			ipconfig -t ${ROUNDTTT} "${DEVICE}"
			;;
		dhcp|bootp|rarp|both)
			ipconfig -t ${ROUNDTTT} -c ${IP} -d "${DEVICE}"
			;;
		*)
			ipconfig -t ${ROUNDTTT} -d $IP

			# grab device entry from ip option
			NEW_DEVICE=${IP#*:*:*:*:*:*}
			if [ "${NEW_DEVICE}" != "${IP}" ]; then
				NEW_DEVICE=${NEW_DEVICE%%:*}
			else
				# wrong parse, possibly only a partial string
				NEW_DEVICE=
			fi
			if [ -n "${NEW_DEVICE}" ]; then
				DEVICE="${NEW_DEVICE}"
			fi
			;;
		esac
	done

# [... skipped code for clarity ....]
}


This function will call ipconfig (from klibc-utils) with a different
ROUNDTTT value each time. The problem is that ipconfig will return a
non-zero value if it fails to get the DHCP value before the timeout.

This is fine if configure_networking has not been called with set -e.
Otherwise it will break things because it makes abort the whole script
on the first failure from ipconfig.


This is part of trace from the initramfs obtained by booting the machine
with the debug parameter in the kernel cmdline.

Begin: Running /scripts/init-premount ... + run_scripts /scripts/init-premount
+ initdir=/scripts/init-premount
+ [ ! -d /scripts/init-premount ]
+ shift
+ . /scripts/init-premount/ORDER
+ /scripts/init-premount/plymouth
+ [ -e /conf/param.conf ]
+ /scripts/init-premount/mandos
calling: settle
IP-Config: eth1 hardware address 0c:14:3a:1b:af:81 mtu 1500 DHCP RARP
IP-Config: eth0 hardware address 0c:14:2a:1b:af:80 mtu 1500 DHCP RARP
IP-Config: no response after 2 secs - giving up
+ [ -e /conf/param.conf ]
+ [ n != y ]
+ log_end_msg
+ _log_msg done.\n
+ [ n = y ]
+ printf done.\n
done.
+ maybe_break mount
+ [  = mount ]
+ log_begin_msg Mounting root file system
+ _log_msg Begin: Mounting root file system ... 
+ [ n = y ]
+ printf Begin: Mounting root file system ... 
Begin: Mounting root file system ... + . /scripts/local
+ . /scripts/nfs
+ . /scripts/local



As you can see, the script /scripts/init-premount/mandos exits as soon as
IP-Config fails on the first try to get IP with a 2 second timeout. 

A possible fix is the following patch:

--- a/usr/share/initramfs-tools/scripts/init-premount/mandos	2016-03-02 10:41:43.437960673 +0100
+++ b/usr/share/initramfs-tools/scripts/init-premount/mandos	2016-03-02 13:00:27.392153826 +0100
@@ -94,7 +94,7 @@
 # If we are connecting directly, run "configure_networking" (from
 # /scripts/functions); it needs IPOPTS and DEVICE
 if [ "${connect+set}" = set ]; then
-    configure_networking
+    configure_networking || true
     if [ -n "$connect" ]; then
 	cat <<-EOF >>/conf/conf.d/mandos/plugin-runner.conf
 	


But there are also other possibilities like disabling set -e on the script.
Maybe there are other functions that can cause trouble.
I have checked all the scripts on my initramfs and only the mandos and the
udev ones are running with set -e.



Attachment: signature.asc
Description: OpenPGP digital signature


Reply to: