Explorar o código

support/scripts: fix and restrict conditions to accept merged dirs

Currently, we accept that the merged usr is backward, i.e. that the
/usr/bin, /usr/sbin, and /usr/lib entries be symlinks to, resp., /bin,
/sbin, and /lib. We also allow either entries to be symlinks to other
parts of the root. Both are accepted despite the comment at the top of
the script explaining what should be accepted.

However, a properly merged usr is the other way around: /bin, /sbin, and
/lib are the symlinks to resp. /usr/bin, /usr/sbin, and /usr/lib, which
are actual directories.

Fix the check-merged-usr script accordingly: implement the test as we
mean it, by testing the conditions rather than resorting to a convoluted
and incorrect use of stat(1).

Even though the split between test_dir() and test_merged() seems
superfluous, it'll come useful when we introduce support for merged-bin
in a later patch.

For skeletons, we require that the directories do exist, while we allow
them to be missing for overlays; indeed, it is perfectly legit to
provide an overlay that only contains totally unrelated directories
(e.g. /var/www to populate a webroot for example).

Extend the heading-comment to be more explicit (and drop '/' as there is
nothing to say about it).

Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
Signed-off-by: Romain Naour <romain.naour@smile.fr>
Yann E. MORIN hai 4 meses
pai
achega
4da66e8130
Modificáronse 1 ficheiros con 48 adicións e 33 borrados
  1. 48 33
      support/scripts/check-merged-usr.sh

+ 48 - 33
support/scripts/check-merged-usr.sh

@@ -2,13 +2,14 @@
 #
 #
 # Check if a given custom skeleton or overlay complies to the merged /usr
 # Check if a given custom skeleton or overlay complies to the merged /usr
 # requirements:
 # requirements:
-# /
-# /bin -> usr/bin
-# /lib -> usr/lib
-# /sbin -> usr/sbin
-# /usr/bin/
-# /usr/lib/
-# /usr/sbin/
+#   /bin            missing, or a relative symlink to usr/bin
+#   /lib            missing, or a relative symlink to usr/lib
+#   /sbin           missing, or a relative symlink to usr/sbin
+#   /usr/bin/       missing*, or an existing directory; not a symlink
+#   /usr/lib/       missing*, or an existing directory; not a symlink
+#   /usr/sbin/      missing*, or an existing directory; not a symlink
+#
+# *: must be present for skeletons, can be missing for overlays
 #
 #
 # Input:
 # Input:
 #   --type TYPE     the type of root to check: 'skeleton' or 'overlay'
 #   --type TYPE     the type of root to check: 'skeleton' or 'overlay'
@@ -17,7 +18,7 @@
 #   stdout:         the list of non-compliant paths (empty if compliant).
 #   stdout:         the list of non-compliant paths (empty if compliant).
 # Exit code:
 # Exit code:
 #   0:              in case of success (stdout will be empty)
 #   0:              in case of success (stdout will be empty)
-#   !0:             if any path is improperly merged
+#   !0:             if any directory to check is improperly merged
 #
 #
 
 
 opts="type:"
 opts="type:"
@@ -38,6 +39,12 @@ while :; do
 	esac
 	esac
 done
 done
 
 
+if [ "${type}" = "skeleton" ]; then
+	strict=true
+else
+	strict=false
+fi
+
 report_error() {
 report_error() {
 	local type="${1}"
 	local type="${1}"
 	local root="${2}"
 	local root="${2}"
@@ -54,44 +61,52 @@ report_error() {
 	is_success=false
 	is_success=false
 }
 }
 
 
-# Extract the inode numbers for all of those directories. In case any is
-# a symlink, we want to get the inode of the pointed-to directory, so we
-# append '/.' to be sure we get the target directory. Since the symlinks
-# can be anyway (/bin -> /usr/bin or /usr/bin -> /bin), we do that for
-# each of them.
-#
-
-is_valid_merged() {
-	local root="${1}"
-	local dir1="${2}"
-	local dir2="${3}"
-	local inode1 inode2
+test_merged() {
+	local type="${1}"
+	local root="${2}"
+	local base="${3}"
+	local dir1="${4}"
+	local dir2="${5}"
 
 
-	inode1="$(stat -c '%i' "${root}${dir1}/." 2>/dev/null)"
-	inode2="$(stat -c '%i' "${root}${dir2}/." 2>/dev/null)"
+	if ! test -e "${root}${base}${dir1}"; then
+		return 0
+	elif [ "$(readlink "${root}${base}${dir1}")" = "${dir2}" ]; then
+		return 0
+	fi
 
 
-	test -z "${inode1}" || test "${inode1}" = "${inode2}"
+	# Otherwise, this directory is not merged
+	report_error "${type}" "${root}" \
+		'%s%s should be missing, or be a relative symlink to %s\n' \
+		"${base}" "${dir1}" "${dir2}"
 }
 }
 
 
-test_merged() {
+test_dir() {
 	local type="${1}"
 	local type="${1}"
 	local root="${2}"
 	local root="${2}"
-	local dir1="${3}"
-	local dir2="${4}"
+	local base="${3}"
+	local dir="${4}"
 
 
-	if ! is_valid_merged "${root}" "${dir1}" "${dir2}"; then
-		report_error "${type}" "${root}" \
-			'%s should be missing, or be a relative symlink to %s\n' \
-			"${dir1}" "${dir2}"
+	if ! test -e "${root}${base}${dir}" && ! ${strict}; then
+		return 0
+	elif test -d "${root}${base}${dir}" && ! test -L "${root}${base}${dir}"; then
+		return 0
 	fi
 	fi
+
+	# Otherwise, this entry is not a proper directory
+	report_error "${type}" "${root}" \
+		"%s%s should exist, be a directory, and not be a symlink\n" \
+		"${base}" "${dir}"
 }
 }
 
 
 is_success=true
 is_success=true
 for root; do
 for root; do
 	first=true
 	first=true
-	test_merged "${type}" "${root}" "/lib" "/usr/lib"
-	test_merged "${type}" "${root}" "/bin" "/usr/bin"
-	test_merged "${type}" "${root}" "/sbin" "/usr/sbin"
+	test_dir "${type}" "${root}" "/" "usr/bin"
+	test_dir "${type}" "${root}" "/" "usr/lib"
+	test_dir "${type}" "${root}" "/" "usr/sbin"
+	test_merged "${type}" "${root}" "/" "bin" "usr/bin"
+	test_merged "${type}" "${root}" "/" "lib" "usr/lib"
+	test_merged "${type}" "${root}" "/" "sbin" "usr/sbin"
 done
 done
 
 
 ${is_success}
 ${is_success}