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 via email to