initrd: Don't enable the root shell by default

Starting an authenticated root shell is a security hole, so don't do
it by default.  The kernel command line parameter
‘initrd.shell_on_fail’ restores the original.  (Of course, this only
improves security if you have a password on GRUB to prevent the kernel
command line from being edited by unauthorized users.)
This commit is contained in:
Eelco Dolstra 2013-01-09 22:31:57 +01:00
parent 91bead9c18
commit 93a7a32bab
2 changed files with 48 additions and 30 deletions

View File

@ -16,15 +16,26 @@ systemd:
<variablelist>
<varlistentry><term><literal>initrd.shell_on_fail</literal></term>
<listitem><para>Start a root shell if something goes wrong in
stage 1 of the boot process (the initial ramdisk). This is
disabled by default because there is no authentication for the
root shell.</para></listitem>
</varlistentry>
<varlistentry><term><literal>debug1</literal></term>
<listitem><para>Request an interactive shell in stage 1 of the
boot process (the initial ramdisk). The shell gets started before
<listitem><para>Start an interactive shell in stage 1 before
anything useful has been done. That is, no modules have been
loaded and no file systems have been mounted, except for
<filename>/proc</filename> and
<filename>/sys</filename>.</para></listitem>
</varlistentry>
<varlistentry><term><literal>debugtrace</literal></term>
<listitem><para>Print every shell command executed by the stage 1
and 2 boot scripts.</para></listitem>
</varlistentry>
<varlistentry><term><literal>single</literal></term>
<listitem><para>Boot into rescue mode (a.k.a. single user mode).
This will cause systemd to start nothing but the unit

View File

@ -1,6 +1,7 @@
#! @shell@
targetRoot=/mnt-root
console=tty1
export LD_LIBRARY_PATH=@extraUtils@/lib
export PATH=@extraUtils@/bin:@extraUtils@/sbin
@ -17,37 +18,31 @@ An error occured in stage 1 of the boot process, which must mount the
root filesystem on \`$targetRoot' and then start stage 2. Press one
of the following keys:
i) to launch an interactive shell;
EOF
if [ -n "$allowShell" ]; then cat <<EOF
i) to launch an interactive shell
f) to start an interactive shell having pid 1 (needed if you want to
start stage 2's init manually); or
*) to ignore the error and continue.
start stage 2's init manually)
EOF
fi
cat <<EOF
r) to reboot immediately
*) to ignore the error and continue
EOF
read reply
# Get the console from the kernel cmdline
console=tty1
for o in $(cat /proc/cmdline); do
case $o in
console=*)
set -- $(IFS==; echo $o)
params=$2
set -- $(IFS=,; echo $params)
console=$1
;;
esac
done
case $reply in
f)
exec setsid @shell@ -c "@shell@ < /dev/$console >/dev/$console 2>/dev/$console" ;;
i)
echo "Starting interactive shell..."
setsid @shell@ -c "@shell@ < /dev/$console >/dev/$console 2>/dev/$console" || fail
;;
*)
echo "Continuing...";;
esac
if [ -n "$allowShell" -a "$reply" = f ]; then
exec setsid @shell@ -c "@shell@ < /dev/$console >/dev/$console 2>/dev/$console"
elif [ -n "$allowShell" -a "$reply" = i ]; then
echo "Starting interactive shell..."
setsid @shell@ -c "@shell@ < /dev/$console >/dev/$console 2>/dev/$console" || fail
elif [ "$reply" = r ]; then
echo "Rebooting..."
reboot -f
else
echo "Continuing..."
fi
}
trap 'fail' 0
@ -76,6 +71,12 @@ mount -t securityfs none /sys/kernel/security
export stage2Init=/init
for o in $(cat /proc/cmdline); do
case $o in
console=*)
set -- $(IFS==; echo $o)
params=$2
set -- $(IFS=,; echo $params)
console=$1
;;
init=*)
set -- $(IFS==; echo $o)
stage2Init=$2
@ -84,13 +85,19 @@ for o in $(cat /proc/cmdline); do
# Show each command.
set -x
;;
initrd.shell_on_fail)
allowShell=1
;;
debug1) # stop right away
allowShell=1
fail
;;
debug1devices) # stop after loading modules and creating device nodes
allowShell=1
debug1devices=1
;;
debug1mounts) # stop after mounting file systems
allowShell=1
debug1mounts=1
;;
stage1panic=1)
@ -180,7 +187,7 @@ onACPower() {
checkFS() {
local device="$1"
local fsType="$2"
# Only check block devices.
if [ ! -b "$device" ]; then return 0; fi
@ -219,7 +226,7 @@ checkFS() {
if test $(($fsckResult | 2)) = $fsckResult; then
echo "fsck finished, rebooting..."
sleep 3
reboot
reboot -f
fi
if test $(($fsckResult | 4)) = $fsckResult; then