[<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