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