Opened 4 years ago

Closed 4 years ago

#12107 closed defect (fixed)

Unbootable initramfs in secure mode

Reported by: dsd Owned by: Quozl
Priority: high Milestone: 13.1.0
Component: ofw - open firmware Version: Software Build 12.1.0-21
Keywords: Cc:
Blocked By: Blocking:
Deployments affected: Action Needed: no action
Verified: no


We've found an initramfs that prevents the system from booting from the secure boot path (i.e. when it is read from a zip file). XO-1.75 running Q4D21.

The system doesn't boot - it hangs with OFW still on screen. Serial shows the only kernel message:

Warning: Neither atags nor dtb found

Here is the failing initramfs:

The system can boot from the same initramfs (unzip it...) with no problems.

I'm testing this against 13.1.0 build 2, but I guess pretty much any build will work. Put these 2 files in /bootpart/boot:

Now boot with:

false to require-signatures?
" \boot"   pn-buf place
" int:" load-from-list drop

If I repack the 12.1.0 released kernel/initramfs using the same method, the system boots OK.

I have verified that it doesn't matter which is used - the problem is triggered when the new is put in place, and doesn't occur with the 12.1.0 released one.

Change History (14)

comment:1 Changed 4 years ago by wmb@…

  • Action Needed changed from never set to add to build
  • Owner changed from wmb@… to Quozl

The problem is that the failing ramdisk size is not a multiple of 4, causing the ramdisk to be moved to a non-aligned location, thus causing the flattened device tree (which is located below the ramdisk) to start at an unaligned address.

Fixed by svn 3310.

Workaround for a quick test:

ok : xx - 4 round-down ; patch xx - linux-place-ramdisk

comment:2 Changed 4 years ago by dsd

Thanks for the quick fix. I've confirmed that padding a zero to the initramfs in question (to meet a divisible-by-4 file size) avoids the problem.

No need for an immediate release; we will want to maintain compatibility with old firmware releases for XO-1.75, so I am adding a workaround in the kernel builder (append zeros to the initramfs to meet a 4 byte boundary).

I guess XO-1/XO-1.5 is unaffected, and for XO-4 we don't have to do the "maintain compatibility" dance yet, so this will be limited to just XO-1.75.

comment:3 Changed 4 years ago by Quozl

  • Action Needed changed from add to build to package
  • Milestone changed from Not Triaged to 1.75-firmware
  • Priority changed from normal to low
  • Status changed from new to assigned
  • Version changed from not specified to Software Build 12.1.0-21

comment:4 Changed 4 years ago by dsd

  • Milestone changed from 1.75-firmware to 13.1.0
  • Priority changed from low to high

This bug is slightly more painful than I thought, because Sam discovered on #12284:

  • This bug was a regression introduced after Q4D17 (I had assumed it was more of a long-standing thing)
  • 12.1.0 ships an XO-1.75 activation initramfs of 5572051 bytes which does not divide by 4

I think the best approach here would be for a new XO-1.75 firmware release for 13.1.0: Q4D21 plus the fix mentioned above.

comment:5 Changed 4 years ago by dsd

...but please don't rush back to work Quozl - we'll wait til you are ready.

comment:6 Changed 4 years ago by Quozl

A build prepared for testing by Daniel.

comment:7 Changed 4 years ago by Quozl

  • Action Needed changed from package to test in build

Q4D23 released.

comment:8 Changed 4 years ago by dsd

Q4D23 still can't boot the above failing files which did work on Q4D21:

Now they start booting the kernel at least, messages include:

rootfs image is not initramfs (compression method gzip not configured); looks like an initrd
RAMDISK: gzip image found at block 0

The same thing happens with the nicaragua build of 12.1.0 which uses a kernel/initramfs from the vmeta repository.

This looks like #12181. Whats not clear to me is: why this worked in Q4D17, and why our kernel doesn't manage to uncompress the initramfs. Since we were also baffled by that in the XO-4 case too, I've investigated:

The root of the problem seems to be the device tree initrd info passed by OFW. For this initramfs of 2122879 bytes, ofw passes: linux,initrd-start=0xbdf9b80 linux,initrd-end=0xc000000

That means that the length calculation produces 2122880 bytes (phys_initrd_size = end - start) which is one too many.

So the kernel reaches unpack_to_rootfs() in init/initramfs.c which tasks itself with uncompressing 2122880 bytes. It finds the gzipped initramfs at the start, and decompresses it, but it realises that it has only uncompressed 2122879 bytes. So it goes around the loop again, trying to find a decompressor for the final byte, and it fails. Thats when the kernel starts producing messages like "gzip compression not supported" - its confused.

So, please check the linux,initrd-end calculation. It looks like it is off by one in this case.

comment:9 Changed 4 years ago by wmb@…

Try this before booting and see if it works:

ok patch noop aligned linux-place-ramdisk

comment:10 Changed 4 years ago by dsd

That fixes it, thanks.

comment:11 Changed 4 years ago by Quozl

  • Action Needed changed from test in build to add to build

Fixed by svn 3463. In Q4D24.

comment:12 Changed 4 years ago by dsd

Thanks! Tested, it fixes booting of the nicaragua 12.1.0 signed image.

comment:13 Changed 4 years ago by dsd

  • Action Needed changed from add to build to test in build

Test in 13.1.0 build 16.

comment:14 Changed 4 years ago by greenfeld

  • Action Needed changed from test in build to no action
  • Resolution set to fixed
  • Status changed from assigned to closed

I can boot 13.1.0 os21 and 12.1.0 os21 on a secured XO-1.75 with Q4D24, both against the activation initramfs and the runtime one.

Note: See TracTickets for help on using tickets.