Skip to content

Add comparator for EFI executables

While investigating why two ostree commits of Endless OS were 120 MB different, despite the only change being an updated Slovenian translation for gnome-control-center, I found that diffoscope cannot compare EFI kernel images. (This was the largest file that different between the two builds.)

file for the EFI kernel image reports:

PE32+ executable (EFI application) x86-64 (stripped to external PDB), for MS Windows

Based on a tip-off on #156, I tried comparing the output of objdump --all-headers --disassemble --line-numbers between the two versions, and this was somewhat informative:

wjt@camille:~$ diff -u <(objdump --all-headers --disassemble --line-numbers old/payg-image.efi) <(objdump --all-headers --disassemble --line-numbers new/payg-image.efi )
--- /dev/fd/63	2020-06-25 13:44:29.736454452 +0100
+++ /dev/fd/62	2020-06-25 13:44:29.736454452 +0100
@@ -1,6 +1,6 @@
 
-old/payg-image.efi:     format de fichier pei-x86-64
-old/payg-image.efi
+new/payg-image.efi:     format de fichier pei-x86-64
+new/payg-image.efi
 architecture: i386:x86-64, fanions 0x00000133:
 HAS_RELOC, EXEC_P, HAS_SYMS, HAS_LOCALS, D_PAGED
 adresse de départ 0x0000000000004000
@@ -15,7 +15,7 @@
 MajorLinkerVersion	2
 MinorLinkerVersion	31
 SizeOfCode		00007800
-SizeOfInitializedData	03cb7000
+SizeOfInitializedData	03cb6c00
 SizeOfUninitializedData	00000000
 AddressOfEntryPoint	0000000000004000
 BaseOfCode		0000000000004000
@@ -31,7 +31,7 @@
 Win32Version		00000000
 SizeOfImage		06153000
 SizeOfHeaders		00000400
-CheckSum		03cc456d
+CheckSum		03cc7d32
 Subsystem		0000000a	(EFI application)
 DllCharacteristics	00000000
 SizeOfStackReserve	0000000000000000
@@ -46,7 +46,7 @@
 Entry 1 0000000000000000 00000000 Import Directory [parts of .idata]
 Entry 2 0000000000000000 00000000 Resource Directory [.rsrc]
 Entry 3 0000000000000000 00000000 Exception Directory [.pdata]
-Entry 4 0000000003cc11a8 000008f8 Security Directory
+Entry 4 0000000003cc0da8 000008f8 Security Directory
 Entry 5 000000000000c000 0000000a Base Relocation Directory [.reloc]
 Entry 6 0000000000000000 00000000 Debug Directory
 Entry 7 0000000000000000 00000000 Description Directory
@@ -85,7 +85,7 @@
                   CONTENTS, ALLOC, LOAD, READONLY, DATA
   8 .linux        00b60830  0000000000040000  0000000000040000  0000ba00  2**2
                   CONTENTS, ALLOC, LOAD, READONLY, DATA
-  9 .initrd       031527c9  0000000003000000  0000000003000000  00b6c400  2**2
+  9 .initrd       03152346  0000000003000000  0000000003000000  00b6c400  2**2
                   CONTENTS, ALLOC, LOAD, READONLY, DATA
 SYMBOL TABLE:
 [  0](sec  1)(fl 0x00)(ty   0)(scl   3) (nx 0) 0x0000000000000028 .exit

The second-largest change between the two images is, indeed, the initramfs, and diffoscope tells me clearly what the problem is:

wjt@camille:~$ docker run --rm -i -w $(pwd) -v $(pwd):$(pwd) registry.salsa.debian.org/reproducible-builds/diffoscope old/initramfs.img new/initramfs.img
--- old/initramfs.img
+++ new/initramfs.img
│┄ comprises of 1 embedded members
├── .cpio file embedded at offset 0
│ ├── file list
│ │ @@ -1,7 +1,7 @@
│ │ -drwxr-xr-x   3        0        0        0 2020-06-23 23:08:12.000000 .
│ │ --rw-r--r--   1        0        0        2 2020-06-23 23:08:12.000000 early_cpio
│ │ -drwxr-xr-x   3        0        0        0 2020-06-23 23:08:12.000000 kernel
│ │ -drwxr-xr-x   3        0        0        0 2020-06-23 23:08:12.000000 kernel/x86
│ │ -drwxr-xr-x   2        0        0        0 2020-06-23 23:08:12.000000 kernel/x86/microcode
│ │ --rw-r--r--   1        0        0    30546 2020-06-23 23:08:12.000000 kernel/x86/microcode/AuthenticAMD.bin
│ │ --rw-r--r--   1        0        0  2860032 2020-06-23 23:08:12.000000 kernel/x86/microcode/GenuineIntel.bin
│ │ +drwxr-xr-x   3        0        0        0 2020-06-24 23:09:16.000000 .
│ │ +-rw-r--r--   1        0        0        2 2020-06-24 23:09:16.000000 early_cpio
│ │ +drwxr-xr-x   3        0        0        0 2020-06-24 23:09:16.000000 kernel
│ │ +drwxr-xr-x   3        0        0        0 2020-06-24 23:09:16.000000 kernel/x86
│ │ +drwxr-xr-x   2        0        0        0 2020-06-24 23:09:16.000000 kernel/x86/microcode
│ │ +-rw-r--r--   1        0        0    30546 2020-06-24 23:09:16.000000 kernel/x86/microcode/AuthenticAMD.bin
│ │ +-rw-r--r--   1        0        0  2860032 2020-06-24 23:09:16.000000 kernel/x86/microcode/GenuineIntel.bin

I believe this is because our dracut is not using --reproducible.

It would be nice if diffoscope could compare EFI executables more neatly than xxd | diff. For extra credit, kernel images with embedded initramfs could be identified and the initramfs compared recursively.

To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information