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 <[email protected]>
---
 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

Reply via email to