diff options
author | Michael Prokop <mika@debian.org> | 2010-07-29 23:28:54 -0400 |
---|---|---|
committer | Michael Prokop <mika@debian.org> | 2010-08-06 23:02:05 -0400 |
commit | e7daaf7fdf80ba63626515ca3e3e3054aaac0417 (patch) | |
tree | 225954a4bff3531fe5fd82b1292024ca801afa4d | |
parent | a4e1a9ea7321799da65a11bb96413d66b7cb07eb (diff) | |
download | initramfs-tools-e7daaf7fdf80ba63626515ca3e3e3054aaac0417.tar.gz initramfs-tools-e7daaf7fdf80ba63626515ca3e3e3054aaac0417.zip |
init: provide validate_init() wrapper to support absolute symlinks.
If /sbin/init is an absolute symlink (e.g. to /bin/systemd) the
readlink check doesn't work as $rootmnt is involved.
The validate_init() shell function takes care of this fact, as
well as when guessing the init binary points to a directory. For
example Ubuntu's upstart has its configuration inside /etc/init
whereas this is considered a valid run_init_process() binary by
the Linux kernel and `test -x' returns true when checking for
executables.
Therefore be more conservative with providing full backwards
compability as well as new added support for absolute symlinks at
the same time.
Closes: #590744
-rwxr-xr-x | init | 40 |
1 files changed, 32 insertions, 8 deletions
@@ -227,24 +227,48 @@ run_scripts /scripts/init-bottom mount -n -o move /sys ${rootmnt}/sys mount -n -o move /proc ${rootmnt}/proc +validate_init() { + checktarget="${1}" + + # Work around absolute symlinks + if [ -d "${rootmnt}" ] && [ -h "${rootmnt}${checktarget}" ]; then + case $(readlink "${rootmnt}${checktarget}") in /*) + checktarget="$(chroot ${rootmnt} readlink ${checktarget})" + ;; + esac + fi + + # Make sure the specified init can be executed + if [ ! -x "${rootmnt}${checktarget}" ]; then + return 1 + fi + + # Upstart uses /etc/init as configuration directory :-/ + if [ -d "${rootmnt}${checktarget}" ]; then + return 1 + fi +} + # Check init bootarg -if [ -n "${init}" ] && [ ! -x "${rootmnt}${init}" ]; then - echo "Target filesystem doesn't have ${init}." - init= +if [ -n "${init}" ]; then + if ! validate_init "$init"; then + echo "Target filesystem doesn't have requested ${init}." + init= + fi fi # Search for valid init if [ -z "${init}" ] ; then - for init in /sbin/init /etc/init /bin/init /bin/sh; do - if [ ! -x "${rootmnt}${init}" ]; then - continue + for inittest in /sbin/init /etc/init /bin/init /bin/sh; do + if validate_init "${inittest}"; then + init="$inittest" + break fi - break done fi # No init on rootmount -if [ ! -x "${rootmnt}${init}" ]; then +if ! validate_init "${init}" ; then panic "No init found. Try passing init= bootarg." fi |