lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20260209153800.28228-1-ansuelsmth@gmail.com>
Date: Mon,  9 Feb 2026 16:37:58 +0100
From: Christian Marangi <ansuelsmth@...il.com>
To: Nathan Chancellor <nathan@...nel.org>,
	Nicolas Schier <nsc@...nel.org>,
	Christian Marangi <ansuelsmth@...il.com>,
	David Disseldorp <ddiss@...e.de>,
	Dmitry Safonov <0x7f454c46@...il.com>,
	linux-kbuild@...r.kernel.org,
	linux-kernel@...r.kernel.org
Subject: [RFC PATCH] initramfs: correctly handle space in path on cpio list generation

The current gen_initramfs.sh and gen_init_cpio.c tools doesn't correctly
handle path or filename with space in it. Although highly discouraged,
Linux also supports filename or path with whiespace and currently this
will produce error on generating and parsing the cpio_list file as the
pattern won't match the expected variables order. (with gid or mode
parsed as string)

This was notice when creating an initramfs with including the ALSA test
files and configuration that have whitespace in both some .conf and even
some symbolic links.

Example error:
usr/gen_initramfs.sh: line 97: [: Devkit.conf: integer expected
usr/gen_initramfs.sh: line 97: [: Devkit.conf: integer expected
usr/gen_initramfs.sh: line 97: [: Nexus: integer expected
usr/gen_initramfs.sh: line 97: [: Tab: integer expected
usr/gen_initramfs.sh: line 98: [: A500: integer expected
usr/gen_initramfs.sh: line 97: [: Slider: integer expected
usr/gen_initramfs.sh: line 98: [: WM8903.conf: integer expected
usr/gen_initramfs.sh: line 97: [: Transformer: integer expected
usr/gen_initramfs.sh: line 98: [: WM8903.conf: integer expected
usr/gen_initramfs.sh: line 97: [: Infinity: integer expected
usr/gen_initramfs.sh: line 98: [: TF700T: integer expected
usr/gen_initramfs.sh: line 97: [: Pad: integer expected
usr/gen_initramfs.sh: line 98: [: TF300T: integer expected
usr/gen_initramfs.sh: line 97: [: Pad: integer expected
usr/gen_initramfs.sh: line 98: [: TF300TG: integer expected
usr/gen_initramfs.sh: line 97: [: Pad: integer expected
usr/gen_initramfs.sh: line 98: [: TF300TL: integer expected
usr/gen_initramfs.sh: line 97: [: Prime: integer expected
usr/gen_initramfs.sh: line 98: [: TF201: integer expected
usr/gen_initramfs.sh: line 97: [: 4X: integer expected
usr/gen_initramfs.sh: line 98: [: HD: integer expected
usr/gen_initramfs.sh: line 97: [: Vu: integer expected
usr/gen_initramfs.sh: line 98: [: MAX98089.conf: integer expected

Caused by example file:

/usr/share/alsa/ucm2/conf.d/tegra/Asus Transformer Pad TF300TL RT5631.conf

To correctly handle this problem, rework the gen_initramfs.sh and
gen_init_cpio.c to guard all the path with "" to handle all kind of
whitespace for filename/path.

The default_cpio_list is also updated to follow this new pattern.

Signed-off-by: Christian Marangi <ansuelsmth@...il.com>
---
 usr/default_cpio_list |  6 +++---
 usr/gen_init_cpio.c   | 10 +++++-----
 usr/gen_initramfs.sh  | 27 +++++++++++++++++++--------
 3 files changed, 27 insertions(+), 16 deletions(-)

diff --git a/usr/default_cpio_list b/usr/default_cpio_list
index 37b3864066e8..d4a66b4aa7f7 100644
--- a/usr/default_cpio_list
+++ b/usr/default_cpio_list
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 # This is a very simple, default initramfs
 
-dir /dev 0755 0 0
-nod /dev/console 0600 0 0 c 5 1
-dir /root 0700 0 0
+dir "/dev" 0755 0 0
+nod "/dev/console" 0600 0 0 c 5 1
+dir "/root" 0700 0 0
diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c
index b7296edc6626..ca5950998841 100644
--- a/usr/gen_init_cpio.c
+++ b/usr/gen_init_cpio.c
@@ -166,7 +166,7 @@ static int cpio_mkslink_line(const char *line)
 	int gid;
 	int rc = -1;
 
-	if (5 != sscanf(line, "%" str(PATH_MAX) "s %" str(PATH_MAX) "s %o %d %d", name, target, &mode, &uid, &gid)) {
+	if (5 != sscanf(line, "\"%" str(PATH_MAX) "[^\"]\" \"%" str(PATH_MAX) "[^\"]\" %o %d %d", name, target, &mode, &uid, &gid)) {
 		fprintf(stderr, "Unrecognized dir format '%s'", line);
 		goto fail;
 	}
@@ -244,7 +244,7 @@ static int cpio_mkgeneric_line(const char *line, enum generic_types gt)
 	int gid;
 	int rc = -1;
 
-	if (4 != sscanf(line, "%" str(PATH_MAX) "s %o %d %d", name, &mode, &uid, &gid)) {
+	if (4 != sscanf(line, "\"%" str(PATH_MAX) "[^\"]\" %o %d %d", name, &mode, &uid, &gid)) {
 		fprintf(stderr, "Unrecognized %s format '%s'",
 			line, generic_type_table[gt].type);
 		goto fail;
@@ -322,7 +322,7 @@ static int cpio_mknod_line(const char *line)
 	unsigned int min;
 	int rc = -1;
 
-	if (7 != sscanf(line, "%" str(PATH_MAX) "s %o %d %d %c %u %u",
+	if (7 != sscanf(line, "\"%" str(PATH_MAX) "[^\"]\" %o %d %d %c %u %u",
 			 name, &mode, &uid, &gid, &dev_type, &maj, &min)) {
 		fprintf(stderr, "Unrecognized nod format '%s'", line);
 		goto fail;
@@ -527,8 +527,8 @@ static int cpio_mkfile_line(const char *line)
 	int end = 0, dname_len = 0;
 	int rc = -1;
 
-	if (5 > sscanf(line, "%" str(PATH_MAX) "s %" str(PATH_MAX)
-				"s %o %d %d %n",
+	if (5 > sscanf(line, "\"%" str(PATH_MAX) "[^\"]\" \"%"
+				str(PATH_MAX) "[^\"]\" %o %d %d %n",
 				name, location, &mode, &uid, &gid, &end)) {
 		fprintf(stderr, "Unrecognized file format '%s'", line);
 		goto fail;
diff --git a/usr/gen_initramfs.sh b/usr/gen_initramfs.sh
index 7eba2fddf0ef..13f2219a1ce9 100755
--- a/usr/gen_initramfs.sh
+++ b/usr/gen_initramfs.sh
@@ -103,7 +103,8 @@ parse() {
 
 	case "${ftype}" in
 		"file")
-			str="${ftype} ${name} ${location} ${str}"
+			printf "%s \"%s\" \"%s\" %s\n" \
+				"${ftype}" "${name}" "${location}" "${str}" >> $cpio_list
 			;;
 		"nod")
 			local dev="`LC_ALL=C ls -l "${location}"`"
@@ -113,19 +114,20 @@ parse() {
 
 			[ -b "${location}" ] && dev="b" || dev="c"
 
-			str="${ftype} ${name} ${str} ${dev} ${maj} ${min}"
+			printf "%s \"%s\" %s %s %s %s\n" \
+				"${ftype}" "${name}" "${str}" "${dev}" "${maj}" "${min}" >> $cpio_list
 			;;
 		"slink")
 			local target=`readlink "${location}"`
-			str="${ftype} ${name} ${target} ${str}"
+			printf "%s \"%s\" \"%s\" %s\n" \
+				"${ftype}" "${name}" "${target}" "${str}" >> $cpio_list
 			;;
 		*)
-			str="${ftype} ${name} ${str}"
+			printf "%s \"%s\" %s\n" \
+				"${ftype}" "${name}" "${str}" >> $cpio_list
 			;;
 	esac
 
-	echo "${str}" >> $cpio_list
-
 	return 0
 }
 
@@ -156,8 +158,17 @@ dir_filelist() {
 
 		echo "${dirlist}" | \
 		while read x; do
-			list_parse $x
-			parse $x
+			# Reverse progressive matching to handle path
+			# with space (last arg)
+			gid=${x##* }
+			x=${x% *}
+			uid=${x##* }
+			x=${x% *}
+			mode=${x##* }
+			path=${x% *}
+
+			list_parse "$path" "$mode" "$uid" "$gid"
+			parse "$path" "$mode" "$uid" "$gid"
 		done
 	fi
 }
-- 
2.51.0


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ