Ticket #12107 (closed defect: fixed)

Opened 2 years ago

Last modified 21 months ago

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:
Action Needed: no action Verified: no
Deployments affected: Blocked By:
Blocking:

Description

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: http://dev.laptop.org/~dsd/20120916/build2-failing/runrd.zip

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 runos.zip is used - the problem is triggered when the new runrd.zip is put in place, and doesn't occur with the 12.1.0 released one.

Change History

Changed 2 years ago by wmb@…

  • owner changed from wmb@… to Quozl
  • next_action changed from never set to add to build

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

Changed 2 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.

Changed 2 years ago by Quozl

  • priority changed from normal to low
  • status changed from new to assigned
  • next_action changed from add to build to package
  • version changed from not specified to Software Build 12.1.0-21
  • milestone changed from Not Triaged to 1.75-firmware

Changed 23 months ago by dsd

  • priority changed from low to high
  • milestone changed from 1.75-firmware to 13.1.0

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.

Changed 23 months ago by dsd

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

Changed 23 months ago by Quozl

A build prepared for testing by Daniel.

Changed 22 months ago by Quozl

  • next_action changed from package to test in build

Q4D23 released.

Changed 22 months 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.

Changed 22 months ago by wmb@…

Try this before booting and see if it works:

ok patch noop aligned linux-place-ramdisk

Changed 22 months ago by dsd

That fixes it, thanks.

Changed 22 months ago by Quozl

  • next_action changed from test in build to add to build

Fixed by svn 3463. In Q4D24.

Changed 22 months ago by dsd

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

Changed 22 months ago by dsd

  • next_action changed from add to build to test in build

Test in 13.1.0 build 16.

Changed 21 months ago by greenfeld

  • status changed from assigned to closed
  • next_action changed from test in build to no action
  • resolution set to fixed

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.