scripts/gen_image_generic.sh: fix order of files in EFI bootfs
authorDaniel Golle <daniel@makrotopia.org>
Thu, 14 Apr 2022 23:46:28 +0000 (00:46 +0100)
committerDaniel Golle <daniel@makrotopia.org>
Fri, 15 Apr 2022 13:12:13 +0000 (14:12 +0100)
mtools recursive copy (mcopy -s ...) is using READDIR(3) to iterate
over the directory entries, hence they end up in the FAT filesystem in
traversal order which breaks reproducibility (rather than being added
to the FAT filesystem in a reproducible order). Implement recursive
copy in gen_image_generic.sh in Shell code instead, as in that way we
can force files to be copied in reproducible order.

Fixes: aece8f5ae8 ("scripts/gen_image_generic.sh: generate reproducible EFI filesystem")
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
(cherry picked from commit 4d289ae7e63893f90957b77962c6b60574d35441)

scripts/gen_image_generic.sh

index 5e37224736ef2bfb72422d6ecf98452a8f17d26e..ef136244029579cb7f85f596bac7b281fe770bd7 100755 (executable)
@@ -26,14 +26,31 @@ KERNELSIZE="$2"
 ROOTFSOFFSET="$(($3 / 512))"
 ROOTFSSIZE="$(($4 / 512))"
 
+# Using mcopy -s ... is using READDIR(3) to iterate through the directory
+# entries, hence they end up in the FAT filesystem in traversal order which
+# breaks reproducibility.
+# Implement recursive copy with reproducible order.
+dos_dircopy() {
+  local entry
+  local baseentry
+  for entry in "$1"/* ; do
+    if [ -f "$entry" ]; then
+      mcopy -i "$OUTPUT.kernel" "$entry" ::"$2"
+    elif [ -d "$entry" ]; then
+      baseentry="$(basename "$entry")"
+      mmd -i "$OUTPUT.kernel" ::"$2""$baseentry"
+      dos_dircopy "$entry" "$2""$baseentry"/
+    fi
+  done
+}
+
 [ -n "$PADDING" ] && dd if=/dev/zero of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc count="$ROOTFSSIZE"
 dd if="$ROOTFSIMAGE" of="$OUTPUT" bs=512 seek="$ROOTFSOFFSET" conv=notrunc
 
 if [ -n "$GUID" ]; then
     [ -n "$PADDING" ] && dd if=/dev/zero of="$OUTPUT" bs=512 seek="$((ROOTFSOFFSET + ROOTFSSIZE))" conv=notrunc count="$sect"
     mkfs.fat --invariant -n kernel -C "$OUTPUT.kernel" -S 512 "$((KERNELSIZE / 1024))"
-    [ "$SOURCE_DATE_EPOCH" ] && find "$KERNELDIR"/ -mindepth 1 -execdir touch -hcd "@${SOURCE_DATE_EPOCH}" "{}" +
-    LC_ALL=C mcopy -m -s -i "$OUTPUT.kernel" "$KERNELDIR"/* ::/
+    LC_ALL=C dos_dircopy "$KERNELDIR" /
 else
     make_ext4fs -J -L kernel -l "$KERNELSIZE" ${SOURCE_DATE_EPOCH:+-T ${SOURCE_DATE_EPOCH}} "$OUTPUT.kernel" "$KERNELDIR"
 fi