Execute scripts from their source location, not the temporary directory.
Remove functions to generate ORDER at boot time.
Closes: #688794
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
---
hook-functions | 10 +++++
mkinitramfs | 17 ++-----
scripts/functions | 131 +++++++++++-------------------------------------------
3 files changed, 40 insertions(+), 118 deletions(-)
diff --git a/hook-functions b/hook-functions
index 2a421cf..957e4c2 100644
--- a/hook-functions
+++ b/hook-functions
@@ -592,3 +592,13 @@ cache_run_scripts()
echo "[ -e /conf/param.conf ] && . /conf/param.conf" >> ${initdir}/ORDER
done
}
+
+run_scripts()
+{
+ scriptdir=${2:-}
+ initdir=${1}
+ [ ! -d ${initdir} ] && return
+
+ runlist=$(get_prereq_pairs | tsort)
+ call_scripts $scriptdir
+}
diff --git a/mkinitramfs b/mkinitramfs
index 8568bbf..07190ed 100755
--- a/mkinitramfs
+++ b/mkinitramfs
@@ -167,13 +167,6 @@ fi
DESTDIR="$(mktemp -d ${TMPDIR:-/var/tmp}/mkinitramfs_XXXXXX)" || exit 1
chmod 755 "${DESTDIR}"
-# do not execute cache_run_scripts() if mounted with noexec
-NOEXEC=""
-fs=$(df -P $DESTDIR | tail -1 | awk '{print $6}')
-if [ -n "$fs" ] && mount | grep -q "on $fs .*noexec" ; then
- NOEXEC=1
-fi
-
__TMPCPIOGZ="$(mktemp ${TMPDIR:-/var/tmp}/mkinitramfs-OL_XXXXXX)" || exit 1
__TMPEARLYCPIO="$(mktemp ${TMPDIR:-/var/tmp}/mkinitramfs-FW_XXXXXX)" || exit 1
@@ -297,13 +290,9 @@ run_scripts /usr/share/initramfs-tools/hooks
run_scripts "${CONFDIR}"/hooks
# cache boot run order
-if [ -n "$NOEXEC" ]; then
- echo "W: TMPDIR is mounted noexec, will not cache run scripts."
-else
- for b in $(cd "${DESTDIR}/scripts" && find . -mindepth 1 -type d); do
- cache_run_scripts "${DESTDIR}" "/scripts/${b#./}"
- done
-fi
+for b in $(cd "${DESTDIR}/scripts" && find . -mindepth 1 -type d); do
+ cache_run_scripts "${DESTDIR}" "/scripts/${b#./}"
+done
# generate module deps
depmod -a -b "${DESTDIR}" ${version}
diff --git a/scripts/functions b/scripts/functions
index 16b5187..7ae9ef3 100644
--- a/scripts/functions
+++ b/scripts/functions
@@ -68,6 +68,20 @@ render()
eval "echo -n \${$@}"
}
+# Find the source for a script file. This is needed to work around
+# temporary directories mounted with the noexec option. The source
+# will be on / or /usr which must be executable.
+get_source()
+{
+ if [ -z "$scriptdir" ]; then
+ echo "${initdir}/$1"
+ elif [ -f "${CONFDIR}${scriptdir}/$1" ]; then
+ echo "${CONFDIR}${scriptdir}/$1"
+ else
+ echo "/usr/share/initramfs-tools${scriptdir}/$1"
+ fi
+}
+
set_initlist()
{
unset initlist
@@ -84,13 +98,6 @@ set_initlist()
;;
esac
- # skip non executable scripts
- if [ ! -x ${si_x} ]; then
- [ "${verbose}" = "y" ] \
- && echo "$si_x ignored: not executable" >&2
- continue
- fi
-
# skip directories
if [ -d ${si_x} ]; then
[ "${verbose}" = "y" ] \
@@ -98,100 +105,23 @@ set_initlist()
continue
fi
- # skip bad syntax
- if ! sh -n ${si_x} ; then
+ si_x="$(get_source "${si_x#${initdir}/}")"
+
+ # skip non executable scripts
+ if [ ! -x ${si_x} ]; then
[ "${verbose}" = "y" ] \
- && echo "$si_x ignored: bad syntax" >&2
+ && echo "$si_x ignored: not executable" >&2
continue
fi
- initlist="${initlist:-} ${si_x#${initdir}/}"
- done
-}
-
-reduce_satisfied()
-{
- deplist="$(render array_${1})"
- unset tmpdeplist
- for rs_y in ${deplist}; do
- # only allow variable name chars
- case ${rs_y} in
- *[![:alnum:]\._-]*)
- continue
- ;;
- esac
- # skip non executable scripts
- [ ! -x ${initdir}/${rs_y} ] && continue
- # skip directories
- [ -d ${initdir}/${rs_y} ] && continue
# skip bad syntax
- sh -n ${initdir}/${rs_y} || continue
-
- tmpdeplist="${tmpdeplist} ${rs_y}"
- done
- deplist=${tmpdeplist}
- for rs_x in ${runlist}; do
- pop_list_item ${rs_x} ${deplist}
- deplist=${tmppop}
- done
- eval array_${1}=\"${deplist}\"
-}
-
-get_prereqs()
-{
- set_initlist
- for gp_x in ${initlist}; do
- tmp=$(${initdir}/${gp_x} prereqs)
- eval array_${gp_x}=\"${tmp}\"
- done
-}
-
-count_unsatisfied()
-{
- set -- ${@}
- return ${#}
-}
-
-# Removes $1 from initlist
-pop_list_item()
-{
- item=${1}
- shift
- set -- ${@}
- unset tmppop
- # Iterate
- for pop in ${@}; do
- if [ ${pop} = ${item} ]; then
+ if ! sh -n ${si_x} ; then
+ [ "${verbose}" = "y" ] \
+ && echo "$si_x ignored: bad syntax" >&2
continue
fi
- tmppop="${tmppop} ${pop}"
- done
-
-}
-# This function generates the runlist, so we clear it first.
-reduce_prereqs()
-{
- unset runlist
- set -- ${initlist}
- i=$#
- # Loop until there's no more in the queue to loop through
- while [ ${i} -ne 0 ]; do
- oldi=${i}
- for rp_x in ${initlist}; do
- reduce_satisfied ${rp_x}
- count_unsatisfied $(render array_${rp_x})
- cnt=${?}
- if [ ${cnt} -eq 0 ]; then
- runlist="${runlist} ${rp_x}"
- pop_list_item ${rp_x} ${initlist}
- initlist=${tmppop}
- i=$((${i} - 1))
- fi
- done
- if [ ${i} -eq ${oldi} ]; then
- panic "PANIC: Circular dependancy. Exiting."
- fi
+ initlist="${initlist:-} ${si_x##*/}"
done
}
@@ -200,7 +130,8 @@ get_prereq_pairs()
set_initlist
for gp_x in ${initlist:-}; do
echo ${gp_x} ${gp_x}
- prereqs=$(${initdir}/${gp_x} prereqs)
+ gp_src="$(get_source $gp_x)"
+ prereqs=$("${gp_src}" prereqs)
for prereq in ${prereqs}; do
echo ${prereq} ${gp_x}
done
@@ -231,21 +162,13 @@ call_scripts()
set +e
}
+# For boot time only; this is overridden at build time in hook-functions
run_scripts()
{
initdir=${1}
[ ! -d ${initdir} ] && return
- if [ -f ${initdir}/ORDER ]; then
- . ${initdir}/ORDER
- elif command -v tsort >/dev/null 2>&1; then
- runlist=$(get_prereq_pairs | tsort)
- call_scripts ${2:-}
- else
- get_prereqs
- reduce_prereqs
- call_scripts
- fi
+ . ${initdir}/ORDER
}
# Load custom modules first
--
Ben Hutchings
Any sufficiently advanced bug is indistinguishable from a feature.
Attachment:
signature.asc
Description: This is a digitally signed message part