rhboot / shim

UEFI shim loader
Other
816 stars 284 forks source link

Why kernel builds do not calculate CheckSum or should it be reset to zero? #612

Closed xnox closed 7 months ago

xnox commented 10 months ago

Currently in Ubuntu we use sbsigntool sbsign & sbattach --attach / --detach to sign EFI binaries, add/remove signatures.

Unfortunately, currently sbsign, sbattach --detach is not roundtrip safe.

# diff -u <(objdump -x ./vmlinuz.pre-signed) <(objdump -x ./vmlinuz.signed-stripped)
--- /dev/fd/63  2023-09-08 19:27:25.237584542 +0000
+++ /dev/fd/62  2023-09-08 19:27:25.237584542 +0000
@@ -1,6 +1,6 @@

-./vmlinuz.pre-signed:     file format pei-x86-64
-./vmlinuz.pre-signed
+./vmlinuz.signed-stripped:     file format pei-x86-64
+./vmlinuz.signed-stripped
 architecture: i386:x86-64, flags 0x00000103:
 HAS_RELOC, EXEC_P, D_PAGED
 start address 0x0000000001b2f74c
@@ -32,7 +32,7 @@
 Win32Version       00000000
 SizeOfImage        03a36000
 SizeOfHeaders      00000200
-CheckSum       00000000
+CheckSum       00b4274b
 Subsystem      0000000a    (EFI application)
 DllCharacteristics 00000000
 SizeOfStackReserve 0000000000000000

It appears that CheckSum header is set to zero's in the initial vmlinuz unsigned binary build. Computed to some value in the signed binary by sbsign, and later computed and updated again by sbattach --detach tool.

My question is who is wrong, and what is best to update?

  1. Should sbattach --remove reset CheckSum field to zero?
  2. Should upstream linux kernel build produce vmlinuz with a correct CheckSum instead of zeros? (or is it binutils?)
  3. Should Ubuntu itself roundtrip upstream linux kernel through sbsign/sbattach --remove to get valid CheckSum field in our unsigned kernels to make them roundtrip safe?
  4. What do other build systems do? and what do other signing tools do?

Looking at Ubuntu unsigned grub builds they have CheckSum zero.

Using pesign to strip signature it seems to calculate the updated CheckSum as well.

Note that pesign seems to calculate the checksum different to the one that sbattach calculates after removing the signature......

# objdump -x ./vmlinuz.pesign-remove | grep CheckSum
CheckSum        00b3ae28
# objdump -x ./vmlinuz.sbattach-remove | grep CheckSum
CheckSum        00b4274b

Is this yet another spec ambiguity, meaning unsigned binaries CheckSum is under defined, and calculated differently by different things, and thus should be ignored?

I feel like proposing for sbattach --remove and pesign --remove-signature to reset CheckSum to zero if no signatures are present, such that one can back the same binaries as the ones submitted for signing at the end of the build. What does everyone else think?

xnox commented 7 months ago

I will change Ubuntu sbattach --remove to reset checksum to zero after removing all signatures, to ensure that sbsign & sbattach --remove are round-trip safe.