Ben Hutchings 3c8b67c9da init: Use run-init -n option to validate real init
validate_init tries to resolve symlinks, but we can't do it properly
without chroot'ing to the real root.  Rather than running readlink
from the real system, use the new run-init -n option.

Closes: #810965
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
2016-01-17 20:01:40 +00:00

308 lines
5.9 KiB
Bash
Executable File

#!/bin/sh
echo "Loading, please wait..."
# Default PATH differs between shells, and is not automatically exported
# by klibc dash. Make it consistent.
export PATH=/sbin:/usr/sbin:/bin:/usr/bin
[ -d /dev ] || mkdir -m 0755 /dev
[ -d /root ] || mkdir -m 0700 /root
[ -d /sys ] || mkdir /sys
[ -d /proc ] || mkdir /proc
[ -d /tmp ] || mkdir /tmp
mkdir -p /var/lock
mount -t sysfs -o nodev,noexec,nosuid sysfs /sys
mount -t proc -o nodev,noexec,nosuid proc /proc
# Note that this only becomes /dev on the real filesystem if udev's scripts
# are used; which they will be, but it's worth pointing out
tmpfs_size="10M"
if [ -e /etc/udev/udev.conf ]; then
. /etc/udev/udev.conf
fi
if ! mount -t devtmpfs -o size=$tmpfs_size,mode=0755 udev /dev; then
echo "W: devtmpfs not available, falling back to tmpfs for /dev"
mount -t tmpfs -o size=$tmpfs_size,mode=0755 udev /dev
[ -e /dev/console ] || mknod -m 0600 /dev/console c 5 1
[ -e /dev/null ] || mknod /dev/null c 1 3
fi
mkdir /dev/pts
mount -t devpts -o noexec,nosuid,gid=5,mode=0620 devpts /dev/pts || true
mount -t tmpfs -o "nosuid,size=20%,mode=0755" tmpfs /run
mkdir -m 0755 /run/initramfs
# Export the dpkg architecture
export DPKG_ARCH=
. /conf/arch.conf
# Set modprobe env
export MODPROBE_OPTIONS="-qb"
# Export relevant variables
export ROOT=
export ROOTDELAY=
export ROOTFLAGS=
export ROOTFSTYPE=
export IP=
export BOOT=
export BOOTIF=
export UBIMTD=
export break=
export init=/sbin/init
export quiet=n
export readonly=y
export rootmnt=/root
export debug=
export panic=
export blacklist=
export resume=
export resume_offset=
export drop_caps=
export fastboot=n
export forcefsck=n
export fsckfix=
# Bring in the main config
. /conf/initramfs.conf
for conf in conf/conf.d/*; do
[ -f ${conf} ] && . ${conf}
done
. /scripts/functions
# Parse command line options
for x in $(cat /proc/cmdline); do
case $x in
init=*)
init=${x#init=}
;;
root=*)
ROOT=${x#root=}
if [ -z "${BOOT}" ] && [ "$ROOT" = "/dev/nfs" ]; then
BOOT=nfs
fi
;;
rootflags=*)
ROOTFLAGS="-o ${x#rootflags=}"
;;
rootfstype=*)
ROOTFSTYPE="${x#rootfstype=}"
;;
rootdelay=*)
ROOTDELAY="${x#rootdelay=}"
case ${ROOTDELAY} in
*[![:digit:].]*)
ROOTDELAY=
;;
esac
;;
nfsroot=*)
NFSROOT="${x#nfsroot=}"
;;
ip=*)
IP="${x#ip=}"
;;
boot=*)
BOOT=${x#boot=}
;;
ubi.mtd=*)
UBIMTD=${x#ubi.mtd=}
;;
resume=*)
RESUME="${x#resume=}"
case $RESUME in
UUID=*)
RESUME="/dev/disk/by-uuid/${RESUME#UUID=}"
esac
;;
resume_offset=*)
resume_offset="${x#resume_offset=}"
;;
noresume)
noresume=y
;;
drop_capabilities=*)
drop_caps="-d ${x#drop_capabilities=}"
;;
panic=*)
panic="${x#panic=}"
case ${panic} in
*[![:digit:].]*)
panic=
;;
esac
;;
quiet)
quiet=y
;;
ro)
readonly=y
;;
rw)
readonly=n
;;
debug)
debug=y
quiet=n
if [ -n "${netconsole}" ]; then
exec >/dev/kmsg 2>&1
else
exec >/run/initramfs/initramfs.debug 2>&1
fi
set -x
;;
debug=*)
debug=y
quiet=n
set -x
;;
break=*)
break=${x#break=}
;;
break)
break=premount
;;
blacklist=*)
blacklist=${x#blacklist=}
;;
netconsole=*)
netconsole=${x#netconsole=}
[ "x$debug" = "xy" ] && exec >/dev/kmsg 2>&1
;;
BOOTIF=*)
BOOTIF=${x#BOOTIF=}
;;
fastboot|fsck.mode=skip)
fastboot=y
;;
forcefsck|fsck.mode=force)
forcefsck=y
;;
fsckfix|fsck.repair=yes)
fsckfix=y
;;
fsck.repair=no)
fsckfix=n
;;
esac
done
# Default to BOOT=local if no boot script defined.
if [ -z "${BOOT}" ]; then
BOOT=local
fi
if [ -n "${noresume}" ]; then
export noresume
unset resume
else
resume=${RESUME:-}
fi
maybe_break top
# Don't do log messages here to avoid confusing graphical boots
run_scripts /scripts/init-top
maybe_break modules
[ "$quiet" != "y" ] && log_begin_msg "Loading essential drivers"
[ -n "${netconsole}" ] && modprobe netconsole netconsole="${netconsole}"
load_modules
[ "$quiet" != "y" ] && log_end_msg
maybe_break premount
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/init-premount"
run_scripts /scripts/init-premount
[ "$quiet" != "y" ] && log_end_msg
maybe_break mount
log_begin_msg "Mounting root file system"
# Always load local and nfs (since these might be needed for /etc or
# /usr, irrespective of the boot script used to mount the rootfs).
. /scripts/local
. /scripts/nfs
. /scripts/${BOOT}
parse_numeric ${ROOT}
maybe_break mountroot
mount_top
mount_premount
mountroot
log_end_msg
if read_fstab_entry /usr; then
log_begin_msg "Mounting /usr file system"
mountfs /usr
log_end_msg
fi
validate_init() {
run-init -n "${rootmnt}" "${1}"
}
# Check init is really there
if ! validate_init "$init"; then
echo "Target filesystem doesn't have requested ${init}."
init=
for inittest in /sbin/init /etc/init /bin/init /bin/sh; do
if validate_init "${inittest}"; then
init="$inittest"
break
fi
done
fi
# Mount cleanup
mount_bottom
nfs_bottom
local_bottom
maybe_break bottom
[ "$quiet" != "y" ] && log_begin_msg "Running /scripts/init-bottom"
run_scripts /scripts/init-bottom
[ "$quiet" != "y" ] && log_end_msg
# Move /run to the root
mount -n -o move /run ${rootmnt}/run
# No init on rootmount
if ! validate_init "${init}" ; then
panic "No init found. Try passing init= bootarg."
fi
maybe_break init
# don't leak too much of env - some init(8) don't clear it
# (keep init, rootmnt, drop_caps)
unset debug
unset MODPROBE_OPTIONS
unset DPKG_ARCH
unset ROOTFLAGS
unset ROOTFSTYPE
unset ROOTDELAY
unset ROOT
unset IP
unset BOOT
unset BOOTIF
unset UBIMTD
unset blacklist
unset break
unset noresume
unset panic
unset quiet
unset readonly
unset resume
unset resume_offset
unset fastboot
unset forcefsck
unset fsckfix
# Move virtual filesystems over to the real filesystem
mount -n -o move /sys ${rootmnt}/sys
mount -n -o move /proc ${rootmnt}/proc
# Chain to real filesystem
exec run-init ${drop_caps} ${rootmnt} ${init} "$@" <${rootmnt}/dev/console >${rootmnt}/dev/console 2>&1
echo "Something went badly wrong in the initramfs."
panic "Please file a bug on initramfs-tools."