From 810421833a21b42fc21133587e55b310faa792b2 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Mon, 7 Apr 2025 01:05:41 +0200 Subject: [PATCH] unmkinitramfs: Stop splitting into "early" and "main" subdirectories We originally unpacked each cpio archive into its own subdirectory for security reasons. Since we are now able to stitch together multiple cpio archives to feed to a single cpio process, that concern no longer applies. We maintained the split up to the release of "trixie" out of concern for possible breakage of callers that relied on this split. Since that release is done, stop splitting and always unpack everything directly into the output directory. Signed-off-by: Ben Hutchings --- debian/tests/unmkinitramfs | 22 ++----- unmkinitramfs.8 | 11 +--- unmkinitramfs.c | 116 ++++--------------------------------- 3 files changed, 21 insertions(+), 128 deletions(-) diff --git a/debian/tests/unmkinitramfs b/debian/tests/unmkinitramfs index af042af..4c4ff8c 100755 --- a/debian/tests/unmkinitramfs +++ b/debian/tests/unmkinitramfs @@ -9,7 +9,7 @@ make_one_archive() { case "$type" in early) - dir_name=kernel + dir_name="kernel/dir$i" ;; main) dir_name="dir$i" @@ -94,23 +94,13 @@ for n_early in 0 1 2; do rm -rf "$AUTOPKGTEST_TMP/reference" mkdir "$AUTOPKGTEST_TMP/reference" for i in $(seq 0 $((n_early - 1))); do - if [ "$i" -eq 0 ]; then - dir_name=early - else - dir_name=early$((i + 1)) - fi - ln -s ../input/"early$i" \ - "$AUTOPKGTEST_TMP/reference/$dir_name" + mkdir -p "$AUTOPKGTEST_TMP/reference/kernel" + ln -s ../../input/"early$i/kernel/dir$i" \ + "$AUTOPKGTEST_TMP/reference/kernel/" done for i in $(seq 0 $((n_main - 1))); do - if [ $n_early = 0 ]; then - ln -s ../input/"main$i/dir$i" \ - "$AUTOPKGTEST_TMP/reference/dir$i" - else - mkdir -p "$AUTOPKGTEST_TMP/reference/main" - ln -s ../../input/"main$i/dir$i" \ - "$AUTOPKGTEST_TMP/reference/main/dir$i" - fi + ln -s ../input/"main$i/dir$i" \ + "$AUTOPKGTEST_TMP/reference/" done # Compare reference and output diff --git a/unmkinitramfs.8 b/unmkinitramfs.8 index a53ba4d..6d0cb47 100644 --- a/unmkinitramfs.8 +++ b/unmkinitramfs.8 @@ -21,14 +21,9 @@ The initramfs image may be a single compressed cpio archive, or the concatenation of any number of uncompressed cpio archives optionally followed by a compressed cpio archive. -When the initramfs image includes one or more "early initramfs" -archives, that is uncompressed archives with microcode or other files -that the kernel uses directly, these are extracted to sub\-directories -named "\fBearly\fR", "\fBearly2\fR", etc., and the other archives are -extracted to a sub\-directory named "\fBmain\fR". - -In a future version of initramfs\-tools this behaviour may change so -that all archives are extracted directly into the given directory. +Earlier versions of this command would in some cases unpack an +initramfs consisting of multiple archives into multiple subdirectories +of the given directory. .SH OPTIONS diff --git a/unmkinitramfs.c b/unmkinitramfs.c index d69fd7a..1cebd6e 100644 --- a/unmkinitramfs.c +++ b/unmkinitramfs.c @@ -255,30 +255,6 @@ static void cpio_close(struct cpio_handle *cpio) free(cpio); } -static bool detect_early_initramfs(FILE *in_file, const char *in_filename) -{ - struct cpio_handle *cpio; - struct cpio_entry entry; - bool ret = false; - off_t start = ftell(in_file); - - cpio = cpio_open(in_file, in_filename); - if (!cpio) - return false; - - while (cpio_get_next(cpio, &entry) > 0) { - if (strncmp(entry.name, "kernel/", 7) == 0) { - ret = true; - break; - } - } - - cpio_close(cpio); - - fseek(in_file, start, SEEK_SET); - return ret; -} - static bool copy_to_pipe(FILE *in_file, const char *in_filename, off_t start, off_t end, int out_pipe) { @@ -519,12 +495,10 @@ int main(int argc, char **argv) bool verbose = false; const char *in_filename; FILE *in_file; - const char *out_dirname = NULL; - char *out_subdirname = NULL; + const char *out_dirname; const char *cpio_optv[3]; int cpio_optc; struct cpio_proc cpio_proc = { 0 }; - unsigned int early_count = 0; bool ok; /* Parse options */ @@ -561,21 +535,20 @@ int main(int argc, char **argv) out_dirname = argv[optind + 1]; if (!mkdir_allow_exist(out_dirname, 0777)) err(1, "%s", out_dirname); - out_subdirname = malloc(strlen(out_dirname) + 20); - if (!out_subdirname) - err(1, "malloc"); } - /* Set up extra options for cpio */ + /* Spawn cpio with appropriate options and pipe */ cpio_optc = 0; if (do_list) { cpio_optv[cpio_optc++] = "--list"; } else { cpio_optv[cpio_optc++] = "-D"; - cpio_optv[cpio_optc++] = out_subdirname; + cpio_optv[cpio_optc++] = out_dirname; } if (verbose) cpio_optv[cpio_optc++] = "-v"; + if (!spawn_cpio(cpio_optc, cpio_optv, &cpio_proc)) + return 1; /* Iterate over archives within the initramfs */ for (;;) { @@ -594,7 +567,7 @@ int main(int argc, char **argv) warn("%s", in_filename); ok = false; } - if (cpio_proc.pid && !write_trailer(cpio_proc.pipe)) + if (!write_trailer(cpio_proc.pipe)) ok = false; break; } @@ -612,86 +585,21 @@ int main(int argc, char **argv) break; } - /* - * Extract the archive to an "early" or "early" - * subdirectory if: - * - We have not already started the main cpio process - * - We are not listing - * - This looks like an early initramfs (uncompressed - * and contains files under kernel/) - */ - if (!cpio_proc.pid && !do_list && - me->format == FORMAT_CPIO_NEW && - detect_early_initramfs(in_file, in_filename)) { - struct cpio_proc early_cpio_proc; - - if (++early_count == 1) - sprintf(out_subdirname, "%s/early", - out_dirname); - else - sprintf(out_subdirname, "%s/early%u", - out_dirname, early_count); - if (!mkdir_allow_exist(out_subdirname, 0777)) { - warn("%s", out_subdirname); - ok = false; - break; - } - if (!spawn_cpio(cpio_optc, cpio_optv, - &early_cpio_proc)) { - ok = false; - break; - } + if (me->format == FORMAT_CPIO_NEW) { ok = handle_uncompressed(in_file, in_filename, - early_cpio_proc.pipe) - && write_trailer(early_cpio_proc.pipe); - if (!end_cpio(&early_cpio_proc, ok)) - ok = false; + cpio_proc.pipe); if (!ok) break; } else { - /* - * Otherwise, extract to either the base - * output directory or a "main" subdirectory, - * depending on whether we already created - * subdirectories. - */ - if (!cpio_proc.pid) { - if (do_list) { - ; - } else if (early_count) { - sprintf(out_subdirname, "%s/main", - out_dirname); - if (!mkdir_allow_exist(out_subdirname, - 0777)) { - warn("%s", out_subdirname); - ok = false; - break; - } - } else { - strcpy(out_subdirname, out_dirname); - } - if (!spawn_cpio(cpio_optc, cpio_optv, - &cpio_proc)) { - ok = false; - break; - } - } - if (me->format == FORMAT_CPIO_NEW) { - ok = handle_uncompressed(in_file, in_filename, - cpio_proc.pipe); - if (!ok) - break; - } else { - ok = handle_compressed(in_file, me->format, - cpio_proc.pipe); - break; - } + ok = handle_compressed(in_file, me->format, + cpio_proc.pipe); + break; } } fclose(in_file); - if (cpio_proc.pid && !end_cpio(&cpio_proc, ok)) + if (!end_cpio(&cpio_proc, ok)) ok = false; return !ok;