Package: nbd-client Version: 1:2.9.23-3 Severity: important Tags: patch
If the user answers some configuration questions incorrectly a faulty /etc/nbd-client configuration file is created. /etc/init.d/nbd-client isn't robust against this and the system fails to boot because /etc/init.d/nbd-client hangs. It's not possible to interrupt at this point, nor is it possible to recover the system by booting to single-user since the script runs even in state S. I had to boot to a live CD to get out of the mess. The problem is two-fold: 1. The debconf process allows a faulty configuration to be created 2. The init.d script doesn't handle a faulty configuration properly I haven't tried to fix (1) since it's always possible for the user to create a bad configuration (eg by giving bad file paths) so the software needs to be able to handle this, and shouldn't cause the system to be unbootable. Some bad configurations result in an error message from nbd and the system continues with booting. However, the init.d script is poorly written in that it doesn't double-quote key variable values, causing strange behaviours when these variables are null, and eventually the hang is caused by calling grep with a single argument on line 159, because NBD_DEVICE[0] is null. My faulty configuration had NBD_TYPE[0]="f" and NBD_DEVICE[0]="", so the device wasn't being skipped in the test on line 150. I manually edited the file to set NBD_TYPE[0]="" but every time there was an upgrade to nbd-client it went back to "f" and I had a non-bootable system again. The patch wraps all configuration-derived variables in double-quotes. -- System Information: Debian Release: wheezy/sid APT prefers testing APT policy: (900, 'testing') Architecture: i386 (x86_64) Kernel: Linux 2.6.39-2-amd64 (SMP w/2 CPU cores) Locale: LANG=en_CA.UTF-8, LC_CTYPE=en_CA.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Versions of packages nbd-client depends on: ii debconf [debconf-2.0] 1.5.40 Debian configuration management sy ii initscripts 2.88dsf-13.11 scripts for initializing and shutt ii libc6 2.13-10 Embedded GNU C Library: Shared lib nbd-client recommends no packages. nbd-client suggests no packages. -- debconf information: nbd-client/device: nbd-client/host: nbd-client/no-auto-config: nbd-client/extra: * nbd-client/killall: false nbd-client/port: nbd-client/type: raw * nbd-client/number: 0
>From d9b70ba363b598eb3e7c0513c9b6af27965d2b70 Mon Sep 17 00:00:00 2001 From: Neil Mayhew <neil_may...@users.sourceforge.net> Date: Mon, 31 Jan 2011 17:12:48 -0700 Subject: [PATCH] Increase robustness against faulty configurations This was causing boot hangups with certain automatically-created configurations. --- debian/nbd-client.init.d | 26 +++++++++++++------------- debian/nbd-client.postinst | 6 +++++- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/debian/nbd-client.init.d b/debian/nbd-client.init.d index 9beffc3..ffbe340 100644 --- a/debian/nbd-client.init.d +++ b/debian/nbd-client.init.d @@ -38,9 +38,9 @@ test -x $DAEMON || exit 0 get_devices() { DEVICES= i=0 - while [ ! -z ${NBD_TYPE[$i]} ] + while [ ! -z "${NBD_TYPE[$i]}" ] do - if [ ${NBD_TYPE[$i]} == "$1" ] + if [ "${NBD_TYPE[$i]}" == "$1" ] then DEVICES="$DEVICES ${NBD_DEVICE[$i]}" fi @@ -94,16 +94,16 @@ case "$1" in modprobe nbd echo -n 'Connecting...' i=0 - while [ ! -z ${NBD_TYPE[$i]} ] + while [ ! -z "${NBD_TYPE[$i]}" ] do # cfq deadlocks NBD devices, so switch to something else if cfq is # selected by default # This doesn't take into account non-udev devnames, but since # there's really no other option these days... - if grep '\[cfq\]' /sys/block/${NBD_DEVICE[$i]/\/dev\//}/queue/scheduler >/dev/null; then - echo deadline > /sys/block/${NBD_DEVICE[$i]/\/dev\//}/queue/scheduler + if grep '\[cfq\]' "/sys/block/${NBD_DEVICE[$i]/\/dev\//}/queue/scheduler" >/dev/null; then + echo deadline > "/sys/block/${NBD_DEVICE[$i]/\/dev\//}/queue/scheduler" fi - if nbd-client -c ${NBD_DEVICE[$i]} >/dev/null + if nbd-client -c "${NBD_DEVICE[$i]}" >/dev/null then echo "${NBD_DEVICE[$i]} already connected, skipping..." else @@ -113,7 +113,7 @@ case "$1" in else name="" fi - $DAEMON ${NBD_HOST[$i]} $name ${NBD_PORT[$i]} ${NBD_DEVICE[$i]} ${NBD_EXTRA[$i]} + $DAEMON "${NBD_HOST[$i]}" $name "${NBD_PORT[$i]}" "${NBD_DEVICE[$i]}" "${NBD_EXTRA[$i]}" echo "connected ${NBD_DEVICE[$i]}" fi i=$(($i + 1)) @@ -147,16 +147,16 @@ case "$1" in activate) echo 'Activating...' i=0 - while [ ! -z ${NBD_TYPE[$i]} ] + while [ ! -z "${NBD_TYPE[$i]}" ] do case ${NBD_TYPE[$i]} in "s") - /sbin/mkswap ${NBD_DEVICE[$i]} - /sbin/swapon ${NBD_DEVICE[$i]} + /sbin/mkswap "${NBD_DEVICE[$i]}" + /sbin/swapon "${NBD_DEVICE[$i]}" echo "${NBD_DEVICE[$i]}: swap activated." ;; "f") - line=$(grep ${NBD_DEVICE[$i]} /etc/fstab | grep "_netdev") + line=$(grep "${NBD_DEVICE[$i]}" /etc/fstab | grep "_netdev") if [ -z "$line" ] then # sysvinit takes care of these. @@ -164,10 +164,10 @@ case "$1" in case "$TERM" in dumb|network|unknown|"") spinner="" ;; esac - /sbin/fsck $spinner -a ${NBD_DEVICE[$i]} + /sbin/fsck $spinner -a "${NBD_DEVICE[$i]}" if [ $? -lt 2 ] then - /bin/mount ${NBD_DEVICE[$i]} + /bin/mount "${NBD_DEVICE[$i]}" echo "${NBD_DEVICE[$i]}: filesystem mounted." else echo "fsck of ${NBD_DEVICE[$i]} failed. Not mounting." diff --git a/debian/nbd-client.postinst b/debian/nbd-client.postinst index 75d3cf4..3c61426 100644 --- a/debian/nbd-client.postinst +++ b/debian/nbd-client.postinst @@ -64,7 +64,7 @@ case "$1" in device=$RET db_get nbd-client/extra$i extra=$RET - [ -e $device ] || mknod $device b 43 $(( $i + 0 )) + [ -e "$device" ] || mknod "$device" b 43 $(( $i + 0 )) db_get nbd-client/type$i case "$RET" in "swap") @@ -77,6 +77,10 @@ case "$1" in type_="r" ;; esac + if [ -z "$host" -o -z "$port" -o -z "$device" ] + then + type_= # Ensure device will be skipped + fi i=$(( $i + 0 )) sed -i -e 's:\(^NBD_DEVICE\['$i'\]\=\).*:\1"'$device'":g' -e \ 's/\(^NBD_TYPE\['$i'\]=\).*/\1"'$type_'"/g' -e \ -- 1.7.5.4