unmkinitramfs: Restore split to "early" and "main" subdirectories
unmkinitramfs
used to assume that any uncompressed cpio archives at
the beginning of an initramfs image belonged to the early initramfs
and only a final compressed archive belonged to the the main
initramfs. If it found any uncompressed archives it extracted them
into "early
", "early2
", etc. subdirectories and the compressed archive
into a "main
" subdirectory.
The reason for using a separate subdirectory for each archive is to
guard against a symlink traversal attack from an untrusted initramfs,
e.g. the extraction of "link
" as a symlink to "/etc
" followed by
"link/shadow
" which overwrites "/etc/shadow
". cpio
itself protects
against this if we extract a single archive into an empty directory,
but not if we extract multiple archives successively into the same
directory.
mkinitramfs
now splits the main initramfs files between uncompressed
and compressed archives. unmkinitramfs
was changed to use
subdirectory names "cpio1
", "cpio2
", etc. since the previous
distinction was no longer valid.
Several packages that integrate with initramfs-tools have autopkgtests
that run unmkinitramfs
and were broken by this new behaviour. It's
also quite possible that there are also user scripts that would also
be broken.
Therefore, try to restore the old behaviour in unmkinitramfs
:
-
Distinguish whether uncompressed archives are "early" or "main" by checking for a kernel/ subdirectory. Currently all filenames the kernel looks for in an early initramfs are in this subdirectory, but we should never create this in the main initramfs.
-
Extract early archives as before, but concatenate any "main" uncompressed archives to a temporary file. Exclude the trailer from them so that
cpio
won't stop early when reading them. -
Pass both the "main" uncompressed archives and the compressed archive to
xcpio
, and make it concatenate the uncompressed and decompressed archives as input tocpio
.
The concatenation in steps 2 and 3 is done to preserve the protection against symlink traversal.