[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[PATCH initramfs-tools 1/2] Always generate ORDER files in mkinitramfs



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


Reply to: