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.
signature.asc
Description: OpenPGP digital signature