intel-microcode seems to result in an invalid initrd

Bug #1507443 reported by Alex M. Lowe on 2015-10-19
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
intel-microcode (Ubuntu)
Undecided
Unassigned

Bug Description

The intel-microcode package seems to have caused my initrd to be corrupt, only extracting the microcode bin file into /kernel/microcode/x86/GenuineIntel.bin

With kernel 4.1 and earlier, this seems not to be an issue, and Ubuntu can still load cryptsetup to decrypt an encrypted root (how I first noticed this). However, as of kernel 4.2 this seems to no longer be the case.

Attached is an initrd created with intel-microcode installed. file detects it as an uncompressed cpio archive (as opposed to a gzip'd one created without intel-microcode installed), and it only extracts a 'kernel' directory.

Alex M. Lowe (lengau) wrote :

The gzipped CPIO archive at file position 0x2c00 is valid:

$ dd if=/tmp/initrd.img-4.2.0-16-generic.bak of=/tmp/initramfs.bin.gz bs=256 skip=44
$ zcat /tmp/initramfs.bin.gz | cpio -t -i >/dev/null
176985 blocks

And the first uncompressed CPIO archive at file position 0 is also valid:

$ cat /tmp/initrd.img-4.2.0-16-generic.bak | cpio -t -i
kernel
kernel/x86
kernel/x86/microcode
kernel/x86/microcode/GenuineIntel.bin
22 blocks

The padding between the two initramfs is a sequence of zeros, and it is aligned to a block/record size of 1024, which is one of the typical block sizes for CPIO archives (cpio block size only affects padding).

The heuristics initramfs-tools "lsinitramfs" uses to locate the next initramfs are incomplete (it does not skip over the padding at the end of each initramfs) and causes zcat to crash (which is likely a bug in zcat itself):

$ lsinitramfs /tmp/initrd.img-4.2.0-16-generic.bak
/tmp/initrd.img-4.2.0-16-generic.bak
kernel
kernel/x86
kernel/x86/microcode
kernel/x86/microcode/GenuineIntel.bin
*** Error in `zcat': double free or corruption (!prev): 0x00000000021efdb0 ***

I will check if something changed in the early initramfs loaders from kernel 4.1 to 4.2, but this is not likely to be the root cause of the problem.

Can you still reproduce this bug with up-to-date kernels (i.e. please test against 4.1.17 and 4.3.5 or 4.4.1) ?

Ok, there are no changes between 4.1 and 4.2 (actually, between 4.1 and 4.2.8) re. either the earlycpio or the initramfs loaders.

So, the problem lies elsewhere.

That said, since I bothered to research this:

EARLY cpio loader (lib/earlycpio.c, loads the microcode data): always skips zero DWORDs (4 bytes) before any cpio header, so it will just concatenate every non-compressed cpio archive and skip any dword-aligned zero padding before, after, or between cpio archive headers. There is one header per file/directory inside the cpio archive.

Note: the early cpio loader does not care for subdirectories, it can find data by the whole path, and that's how microcode is loaded. This means the cpio archive with microcode does not need to have any of the subdirectories inside, it doesn't matter to the kernel.

LATE cpio loader (init/initramfs.c, loads the real initramfs):
  1. Skips any zero bytes before the compressed or uncompressed data (thus, skips any padding between cpio archives).
  2. Unpacks any compressed or uncompressed cpio archive it finds, concatenating the contents (thus, it *will* also unpack
      the microcode in the first cpio archive, and this file will be available inside the initramfs).
  3. It *depends* on subdirectories being created *first* before any files inside them. If this is not done, it will ignore the file.
  4. It does NOT skip inital zero-padding on the *decompressed* data (i.e. if you compress a cpio archive, it must not have
      any initial zero padding).
  5. It skips any zero padding at the end (compressed or not), but the zeros must *end* at a DWORD boundary.

So, we need more data to debug this. Because the kernel should have been able to read and unpack that initramfs just fine. The boot log (with the exact error message) or a better description of exactly where (and how) things went wrong during the boot would help.

Changed in intel-microcode (Ubuntu):
status: New → Incomplete
Launchpad Janitor (janitor) wrote :

[Expired for intel-microcode (Ubuntu) because there has been no activity for 60 days.]

Changed in intel-microcode (Ubuntu):
status: Incomplete → Expired
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers