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 <benh@debian.org>
Add a test that exercises unmkinitramfs with:
- 0-2 early cpio archives
- 0-2 main cpio archives
- All supported compressors, including none, for the last main archive
and verifies that the output is as expected.
Signed-off-by: Ben Hutchings <benh@debian.org>
Since unmkinitramfs is now native code, it needs to be built as part
of an arch:any package. Introduce initramfs-tools-bin and move it
there.
CI: Remove the variables that disable arch:any builds.
Signed-off-by: Ben Hutchings <benh@debian.org>
Parsing uncompressed cpio archives in this shell script requires
running multiple processes for each archive member.
This was not too bad when there were usually only a few microcode
blobs in an uncompressed archive, but now that we put compressed
kernel modules in an uncompressed archive, it became very slow indeed.
Rewrite it in C so that it's acceptably fast.
This should have no functional changes, except that it adds support
for an initramfs with no compressed part.
Fixes: 81fd41f72dd8 ("Put compressed kernel modules and firmware in an uncompressed cpio")
Signed-off-by: Ben Hutchings <benh@debian.org>
The driver for coreboot firmware-initialized framebuffer can be built as
a module. Debian kernels so far have it as built-in because they would
not be probed automatically when built as a module. This is fixed now,
likely with a patchset included in v6.9-rc1, so we might encounter it as
a module either in Debian or with custom-built kernels.
For MODULES=dep, check for the coreboot framebuffer in a different block
from other platform drivers, and include the framebuffer_coreboot module
if we find the device. For MODULES=most, add driver to the framebuffer
modules list. Explicitly try to probe the module for break=top because
it would not automatically probe there otherwise. Since it requires a
driver for the "simple-framebuffer" device, add simpledrm and simplefb
as its hidden dependencies.
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
Recent Debian kernels have the simplefb driver built-in on a few
architectures, except in cloud flavours. It handles 'simple-framebuffer'
devices registered from elsewhere: possibly in a device-tree fragment,
or from another driver like framebuffer_coreboot, or via SYSFB_SIMPLEFB.
The more modern alternative to it is simpledrm which also handles
the same 'simple-framebuffer' devices.
We haven't switched to simpledrm, but if we do it's possible we will
want it to be a module, since it depends on the drm subsystem and would
require that to be built-in otherwise. Regardless of what we choose for
Debian kernels, it's still possible for custom-built kernels to have
either/both of simplefb and simpledrm as modules instead of built-in.
Include these modules in initramfs unconditionally when MODULES=dep.
For MODULES=most, add the two drivers to the framebuffer modules list.
When MODULES=dep and these drives are (probed) modules, our check for
platform framebuffers always finds a "module" directory in the driver's
sysfs directory and incorrectly skips handling graphics modules, ignore
the false positive.
Unfortunately, these drivers sometimes do not get probed automatically.
One such case is efifb with SYSFB_SIMPLEFB=y, which is quite important.
Add a init-top script that tries to probe simpledrm, with a fallback to
simplefb. Explicitly try to probe these modules for break=top as well.
Signed-off-by: Alper Nebi Yasak <alpernebiyasak@gmail.com>
When installing/upgrading packages (e. g. a kernel and initramfs-tools),
the same initrd is generated twice:
```
$ apt-get install --no-install-recommends -y zstd initramfs-tools linux-image-generic
[...]
Setting up initramfs-tools-core (0.146) ...
Setting up initramfs-tools (0.146) ...
update-initramfs: deferring update (trigger activated)
Setting up linux-image-6.12.20-amd64 (6.12.20-1) ...
I: /vmlinuz.old is now a symlink to boot/vmlinuz-6.12.20-amd64
I: /initrd.img.old is now a symlink to boot/initrd.img-6.12.20-amd64
I: /vmlinuz is now a symlink to boot/vmlinuz-6.12.20-amd64
I: /initrd.img is now a symlink to boot/initrd.img-6.12.20-amd64
/etc/kernel/postinst.d/initramfs-tools:
update-initramfs: Generating /boot/initrd.img-6.12.20-amd64
Setting up linux-image-amd64 (6.12.20-1) ...
Processing triggers for initramfs-tools (0.146) ...
update-initramfs: Generating /boot/initrd.img-6.12.20-amd64
```
Remember the timestamp when the dpkg trigger is set in the file
`/run/update-initramfs.dpkg-trigger`. Then only update the initramfs if
it is not newer than the time the trigger was created.
This will solve the example given above:
```
$ apt-get install --no-install-recommends -y zstd initramfs-tools linux-image-generic
[...]
Setting up initramfs-tools-core (0.146) ...
Setting up initramfs-tools (0.146) ...
update-initramfs: deferring update (trigger activated)
Setting up linux-image-6.12.20-amd64 (6.12.20-1) ...
I: /vmlinuz.old is now a symlink to boot/vmlinuz-6.12.20-amd64
I: /initrd.img.old is now a symlink to boot/initrd.img-6.12.20-amd64
I: /vmlinuz is now a symlink to boot/vmlinuz-6.12.20-amd64
I: /initrd.img is now a symlink to boot/initrd.img-6.12.20-amd64
/etc/kernel/postinst.d/initramfs-tools:
update-initramfs: Generating /boot/initrd.img-6.12.20-amd64
Setting up linux-image-amd64 (6.12.20-1) ...
Processing triggers for libc-bin (2.41-6) ...
Processing triggers for initramfs-tools (0.146) ...
update-initramfs: /boot/initrd.img-6.12.20-amd64 has already been updated since Tue Mar 25 11:48:49 2025.
```
This approach will not help, when the update-initramfs trigger is set by
another package (e. g. clevis-initramfs). That would need support from
the dpkg trigger (see Debian bug #1099136).
LP: #1466965
When installing/upgrading packages (e. g. a kernel and initramfs-tools),
the same initrd is generated twice:
```
$ apt-get install --no-install-recommends -y zstd initramfs-tools linux-image-generic
[...]
Setting up initramfs-tools-core (0.145) ...
Setting up initramfs-tools (0.145) ...
update-initramfs: deferring update (trigger activated)
Setting up linux-image-6.12.16-amd64 (6.12.16-1) ...
I: /vmlinuz.old is now a symlink to boot/vmlinuz-6.12.16-amd64
I: /initrd.img.old is now a symlink to boot/initrd.img-6.12.16-amd64
I: /vmlinuz is now a symlink to boot/vmlinuz-6.12.16-amd64
I: /initrd.img is now a symlink to boot/initrd.img-6.12.16-amd64
/etc/kernel/postinst.d/initramfs-tools:
update-initramfs: Generating /boot/initrd.img-6.12.16-amd64
Setting up linux-image-amd64 (6.12.16-1) ...
Processing triggers for libc-bin (2.40-7) ...
Processing triggers for initramfs-tools (0.145) ...
update-initramfs: Generating /boot/initrd.img-6.12.16-amd64
```
Add a `-s` parameter to `update-initramfs` to set a Unix time stamp
(seconds since 1970) for the update mode. An existing initramfs will
only be updated if it is not newer than the specified Unix time stamp.
This feature is the first step to avoid generating the initrd twice.
LP: #1466965
dracut-install can filter modules by symbol (`--mod-filter-symbol`) to
select modules more fine-grain. Harmonize the set of modules that
initramfs-tools and dracut install.
The modules mptfc, mptsas, mptscsih, mptspi, and zfcp are covered by
including `=drivers/message/fusion` to the block devices.
LP: #2031841
Signed-off-by: Benjamin Drung <benjamin.drung@canonical.com>
Including only UFS storage drivers that match the symbol regexp
`${blockfuncs}|iscsi_register_transport` is not enough.
Move UFS storage drivers to the `block` class instead of the more
specific `scsi`.
LP: #2081020
Ubuntu's dracut package ships an `update-initramfs` command with the
same interface as initramfs-tools'. The difference is that it calls
dracut instead of mkinitramfs.
When installing dracut without purging initramfs-tools,
`/etc/kernel/postinst.d/initramfs-tools` will still execute
`update-initramfs` (in addition to dracut's kernel postinst hook).
So query the newly add `--version` parameter to determine which package
provided the `update-initramfs` script. Only run the kernel postinst
hook when the provider matches.
The current behaviour of creating sub-directories for multi-archive
initramfs images was never documented. Document what we do now, with
a note that we may stop creating sub-directories in future.
Signed-off-by: Ben Hutchings <benh@debian.org>
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:
1. 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.
2. 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.
3. Pass both the "main" uncompressed archives and the compressed
archive to xcpio, and make it concatenate the uncompressed and
decompressed archives as input to cpio.
The concatenation in steps 2 and 3 is done to preserve the protection
against symlink traversal.
Fixes: 81fd41f72dd8 ("Put compressed kernel modules and firmware in an uncompressed cpio")
Fixes: cb0618177b26 ("unmkinitramfs: use directory names 'cpio1', 'cpio2', etc.")
Closes: #1100008
Signed-off-by: Ben Hutchings <benh@debian.org>
We currently split the initramfs when we see zero padding after an
file rather than a new file header. However, the real EOF marker in a
cpio archive is a file header with the name "TRAILER!!!". Look for
that first, then skip zero padding after it.
Signed-off-by: Ben Hutchings <benh@debian.org>
Currently we extract the compressed archive from the initramfs to a
temporary file, but in future we will need to extract multiple
archives. Create a temporary directory at the top level of the
script, and put the compressed archive inside that.
Signed-off-by: Ben Hutchings <benh@debian.org>
chroots and other build environments often do not have /sys mounted.
Nevertheless they want to build initrds. As a complication, live-boot
calls these functions from a hook that has "set -e" turned on, turning
the ignored error from "read" into an abort of update-initramfs.
Fixes: b3e8cc4011334b6f39ba915149d5518b1644f87b
Bug: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1099461
Signed-off-by: Chris Hofstaedtler <zeha@debian.org>
Reset drivers are currently included when MODULES=most but not when
MODULES=dep. Since they are outside the device model, match them by
module name not by driver class.
Closes: #1027458
Signed-off-by: Ben Hutchings <benh@debian.org>