Fix "can't shift that many" crash with empty /proc/cmdline
authorWill Woods <wwoods@redhat.com>
Mon, 16 May 2011 23:17:57 +0000 (19:17 -0400)
committerHarald Hoyer <harald@redhat.com>
Tue, 17 May 2011 08:29:48 +0000 (10:29 +0200)
If /proc/cmdline is empty (like if root=... is set in /etc/cmdline),
modules.d/99base/init will crash with a message saying "can't shift that
many" right before switch_root. The problem is in the block of code that
tries to look for init args. It does something like:

read CMDLINE </proc/cmdline
    [...]
    set $CMDLINE
    shift

If CMDLINE="" then "set $CMDLINE" will dump all the variables to stdout.
(That should be "set -- $CMDLINE" instead.) Since there's no $1, the
"shift" causes an error, and dracut crashes.

The 'shift' was copy-and-pasted from the previous block. It doesn't
belong here; remove it.

[Harald Hoyer <harald@redhat.com>: corrected commit message]
[Harald Hoyer <harald@redhat.com>: fixed indention]

Signed-off-by: Will Woods <wwoods@redhat.com>
modules.d/99base/init

index e2c34c7..8308502 100755 (executable)
@@ -361,19 +361,18 @@ if getarg init= >/dev/null ; then
     ignoreargs="console BOOT_IMAGE"
     # only pass arguments after init= to the init
     CLINE=${CLINE#*init=}
-        set $CLINE
-        shift
-        for x in "$@"; do
-            for s in $ignoreargs; do
-                [ "${x%%=*}" = $s ] && continue 2
-            done
-            initargs="$initargs $x"
+    set -- $CLINE
+    shift # clear out the rest of the "init=" arg
+    for x in "$@"; do
+        for s in $ignoreargs; do
+            [ "${x%%=*}" = $s ] && continue 2
         done
-        unset CLINE
+        initargs="$initargs $x"
+    done
+    unset CLINE
 else
     set +x # Turn off debugging for this section
-    set $CLINE
-    shift
+    set -- $CLINE
     for x in "$@"; do
         case "$x" in
             [0-9]|s|S|single|emergency|auto ) \