boot: exclude the trailing padding from initrd size in initrd_prepare()

This is a follow-up for f8fa4222c9 (boot: Make
initrd_prepare() semantically equivalent to combine_initrds()). That commit
changed the way that the initrd is prepared for type#1 boot loader entries,
also effectively rounding up the sizes to a multiple of 4. In [1], downstream
packagers report that the trailing zeroes result in the calculated hash being
different. To restore compatibility with previous hash calculations and
signatures, change the reported size by excluding the trailing padding. This
should restore the calculation results for the case where only one initrd is
used.

This patch doesn't touch the stub, i.e. doesn't change behaviour for UKIs. The
seems fine, since we didn't change that recently, so any changes there would
break compatiblity. The measurement results for type#1 and type#2 entries are
generally going to be different anyway. ukify and systemd-measure are also out
of scope here, because they are for UKIs.

Fixes https://github.com/systemd/systemd/issues/35439.
The other changes to the way the initrd is constructed are kept, so hopefully
the original issue with booting in qemu is not recreated.

[1] https://bugzilla.suse.com/show_bug.cgi?id=1233752

My simple test: I'm booting a QEMU VM with systemd-boot and a type#1 entry.
With old systemd-boot:
$ sudo systemd-pcrlock log | grep 'kernel-initrd.*event-tag'
  9 █ kernel-initrd  event-tag  - a337a8321bf81de5c53a842843e8f9a926f73a676e5620ff76df94d1c66bc931 F   - Linux: kernel command line
  9 █ kernel-initrd  event-tag  - aec1aee5358bde36f5498f2dc243dec2b103f81242de57b887a11f53677f1272 F   - Linux: initrd
With updated systemd-boot:
$ sudo systemd-pcrlock log | grep 'kernel-initrd.*event-tag'
  9 █ kernel-initrd  event-tag  - a337a8321bf81de5c53a842843e8f9a926f73a676e5620ff76df94d1c66bc931 F   - Linux: kernel command line
  9 █ kernel-initrd  event-tag  - 3ccaa710304aef8734a20265ea7fd3dd67d5461c6b3309c6d30d5c7d2a3ae7f9 F   - Linux: initrd
This matches the initrd hash:
$ sudo sha256sum /efi//26f948d2082e4ae89f5a3af351b63149/6.12.0-rc4+/initrd-dracut
3ccaa710304aef8734a20265ea7fd3dd67d5461c6b3309c6d30d5c7d2a3ae7f9  /efi//26f948d2082e4ae89f5a3af351b63149/6.12.0-rc4+/initrd-dracut
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2024-12-09 15:14:03 +01:00
parent f7f5ba0192
commit 423de11f04
+11 -4
View File
@@ -2446,7 +2446,7 @@ static EFI_STATUS initrd_prepare(
_cleanup_free_ char16_t *options = NULL;
EFI_STATUS err;
size_t size = 0;
size_t size = 0, padded_size = 0;
STRV_FOREACH(i, entry->initrd) {
_cleanup_free_ char16_t *o = options;
@@ -2465,11 +2465,14 @@ static EFI_STATUS initrd_prepare(
if (err != EFI_SUCCESS)
return err;
if (!INC_SAFE(&size, ALIGN4(info->FileSize)))
size_t inc = info->FileSize;
if (!INC_SAFE(&padded_size, ALIGN4(inc)))
return EFI_OUT_OF_RESOURCES;
assert_se(INC_SAFE(&size, *(i + 1) ? ALIGN4(inc) : inc));
}
_cleanup_pages_ Pages pages = xmalloc_initrd_pages(size);
_cleanup_pages_ Pages pages = xmalloc_initrd_pages(padded_size);
uint8_t *p = PHYSICAL_ADDRESS_TO_POINTER(pages.addr);
STRV_FOREACH(i, entry->initrd) {
@@ -2501,7 +2504,11 @@ static EFI_STATUS initrd_prepare(
continue;
memzero(p, pad);
p += pad;
/* Exclude the trailing pad from size calculations. This would change the
* calculated hash, see https://github.com/systemd/systemd/issues/35439
* and https://bugzilla.suse.com/show_bug.cgi?id=1233752. */
if (*(i + 1))
p += pad;
}
assert(PHYSICAL_ADDRESS_TO_POINTER(pages.addr + size) == p);