#991926 grub2: reproducible builds: timestamps in info pages

Package:
src:grub2
Source:
grub2
Submitter:
Vagrant Cascadian
Date:
2026-07-16 19:41:01 UTC
Severity:
normal
Tags:
#991926#5
Date:
2021-08-05 21:56:43 UTC
From:
To:
Timestamps are embedded in the info pages shipped in grub2-common:

https://tests.reproducible-builds.org/debian/rb-pkg/bullseye/amd64/diffoscope-results/grub2.html

  ./usr/share/info/grub.info-1.gz

  ...27·August·2022
  vs.
  ...24·July·2021


The attached patches fix this by removing the UPDATED parts from
docs/grub-dev.texi and docs/grub.texi.


There are still several other outstanding issues affecting the
reproducibility of grub2(including other timestamp issues), but this
should help reduce the differences to troubleshoot the remaining issues.


Thanks for maintaining grub2!


live well,
  vagrant

#991926#10
Date:
2026-06-01 05:05:25 UTC
From:
To:
I have confirmed that this issue is still present and that the patch
fixes the issue.

Would you be amenable to an NMU of grub2 to fix this timestamp issue
(#991926) and several of the other outstanding reproducibility issues?

https://bugs.debian.org/991928 (locales)
https://bugs.debian.org/991927 (/bin/sh vs. /bin/bash)
https://bugs.debian.org/1138608 (ordering in lintian overrides)

There are still some remaining issues, but this would at least fix a few
of the packages produced by grub2 that are not building reproducibly:

https://reproduce.debian.net/excuses.html?source_name=grub2


Am looking at the other issues too, but since some are nearly 5 years
old... it would be nice to get them fixed to reduce the noise. :)


live well,
  vagrant

#991926#15
Date:
2026-07-16 19:39:29 UTC
From:
To:
I have uploaded an NMU to DELAYED/10 with the following changes:

diff -Nru grub2-2.14/debian/changelog grub2-2.14/debian/changelog
--- grub2-2.14/debian/changelog	2026-06-23 08:04:12.000000000 -0700
+++ grub2-2.14/debian/changelog	2026-07-16 11:45:44.000000000 -0700
@@ -1,3 +1,24 @@
+grub2 (2.14-3.1) unstable; urgency=medium
+
+  * Non-maintainer upload.
+
+  [ Vagrant Cascadian ]
+  * Remove updated timestamps from grub.texi and grub-dev.texi.
+    (Closes: #991926)
+  * debian/rules: Sort calls to find when generating lintian overrides.
+    (Closes: #1138608)
+  * debian/rules: pass SHELL=/bin/bash to configure. (Closes: #991927)
+  * debian/rules: export LC_ALL=C.UTF-8 to ensure consistent sort order.
+    (Closes: #991928)
+  * debian/platform-subst: Use sorted list of cpu_platforms.
+    (Closes: #1138611)
+
+  [ James Addison ]
+  * grub2: please build rescue ISO and floppy reproducibly.
+    (Closes: #787795)
+
+ -- Vagrant Cascadian <vagrant@reproducible-builds.org>  Thu, 16 Jul 2026 11:45:44 -0700
+
 grub2 (2.14-3) unstable; urgency=medium

   * Really do not append file/line prefixes to error message
diff -Nru grub2-2.14/debian/patches/bug787795-grub2-please-build-rescue-iso-.patch grub2-2.14/debian/patches/bug787795-grub2-please-build-rescue-iso-.patch
--- grub2-2.14/debian/patches/bug787795-grub2-please-build-rescue-iso-.patch	1969-12-31 16:00:00.000000000 -0800
+++ grub2-2.14/debian/patches/bug787795-grub2-please-build-rescue-iso-.patch	2026-07-16 11:45:44.000000000 -0700
@@ -0,0 +1,104 @@
+From: James Addison <jay@jp-hosting.net>
+Date: Wed, 2 Oct 2024 12:05:20 +0100
+X-Dgit-Generated: 2.14-3.1 db24136aef7571551a9cbad0b6e743297d759f30
+Subject: Bug#787795: grub2: please build rescue ISO and floppy reproducibly
+
+Package: grub2
+Followup-For: Bug #787795
+X-Debbugs-Cc: dkg@fifthhorseman.net, vagrant@reproducible-builds.org
+Control: tags -1 patch
+
+Hi,
+
+On Fri, 05 Jun 2015 02:37:38 -0400, Daniel wrote:
+> > However, it won't be completely reproducible until we get a newer
+> > version of xorriso in debian so that we can "-alter_date_r c" (see
+> > #787793, which blocks this bug).
+
+On Sun, 25 Jul 2021 16:19:46 -0700, Vagrant wrote:
+> Since newer versions of xorriso are now in Debian, I tried adding
+> "-alter_date_r c" to xorriso calls, but it would seem xorriso doesn't
+> support "-alter_date_r c" when used with "-as mkisofs". I'm not sure how
+> difficult it would be to convert away from using "-as mkisofs" so that
+> "-alter_date_r c" would be supportable...
+
+>From inspecting the grub codebase and the commandline options to both xorriso
+and xorrisofs (aka "xorriso -as mkisofs").. although it may in theory be
+possible to convert to 'native' xorriso by migrating a lot of the command-line
+construction, I think that it might be fragile and unnecessary work, because:
+
+...there is a '--set_all_file_dates' command-line option[1] in xorrisofs that
+seems to do what we want here.
+
+There's one other change required in grub-mkrescue alongside this in order to
+achieve reproducible builds: we need it to read from the SOURCE_DATE_EPOCH env
+var when set (currently grub-mkrescue always uses system clock time).
+
+Please find attached a patch that allows me to rebuild grub-rescue-cdrom.iso
+deterministically on my local machine when SOURCE_DATE_EPOCH is set.  I'll also
+offer this as a merge request on the Salsa repository[2].
+
+Note: the current patch _always_ adds the set_all_file_dates option when
+invoking xorriso, regardless of whether the image creation time is read from
+the SOURCE_DATE_EPOCH variable or the system clock.
+
+Regards,
+James
+
+[1] - https://manpages.debian.org/bookworm/xorriso/xorrisofs.1.en.html#set_all_file_dates
+
+[2] - https://salsa.debian.org/grub-team/grub/
+
+From: James Addison <jay@jp-hosting.net>
+Date: Tue, 01 Oct 2024 22:36:39 +0100
+Subject: grub2: build rescue ISO reproducibly
+
+Extend the xorriso command-line invocation to configure a specific
+timestamp for all files during creation of Grub rescue ISO images.
+
+The timestamp to use is read from the SOURCE_DATE_EPOCH environment
+variable when it is set.
+
+Bug-Debian: https://bugs.debian.org/787795
+
+---
+
+diff --git a/util/grub-mkrescue.c b/util/grub-mkrescue.c
+index e7b9078ab..d003f78d9 100644
+--- a/util/grub-mkrescue.c
++++ b/util/grub-mkrescue.c
+@@ -580,7 +580,13 @@ main (int argc, char *argv[])
+   {
+     time_t tim;
+     struct tm *tmm;
+-    tim = time (NULL);
++    /* https://reproducible-builds.org/docs/source-date-epoch/ */
++    char *source_date_epoch;
++    /* This assumes that the SOURCE_DATE_EPOCH environment variable will contain
++       a correct, positive integer in the time_t range */
++    if ((source_date_epoch = getenv("SOURCE_DATE_EPOCH")) == NULL ||
++        (tim = (time_t)strtoll(source_date_epoch, NULL, 10)) <= 0)
++            time(&tim);
+     tmm = gmtime (&tim);
+     iso_uuid = xmalloc (55);
+     grub_snprintf (iso_uuid, 50,
+@@ -604,6 +610,19 @@ main (int argc, char *argv[])
+     xorriso_push (uuid_out);
+     free (uuid_out);
+   }
++  {
++    char *uuid_out = xmalloc (strlen (iso_uuid) + 1);
++    char *optr;
++    const char *iptr;
++    optr = grub_stpcpy (uuid_out, "");
++    for (iptr = iso_uuid; *iptr; iptr++)
++      if (*iptr != '-')
++	*optr++ = *iptr;
++    *optr = '\0';
++    xorriso_push ("--set_all_file_dates");
++    xorriso_push (uuid_out);
++    free (uuid_out);
++  }
+
+   /* build BIOS core.img.  */
+   if (source_dirs[GRUB_INSTALL_PLATFORM_I386_PC])
diff -Nru grub2-2.14/debian/patches/remove-updated-timestamps-from-grub.texi.patch grub2-2.14/debian/patches/remove-updated-timestamps-from-grub.texi.patch
--- grub2-2.14/debian/patches/remove-updated-timestamps-from-grub.texi.patch	1969-12-31 16:00:00.000000000 -0800
+++ grub2-2.14/debian/patches/remove-updated-timestamps-from-grub.texi.patch	2026-07-16 11:45:44.000000000 -0700
@@ -0,0 +1,60 @@
+From: Vagrant Cascadian <vagrant@reproducible-builds.org>
+Date: Mon, 26 Jul 2021 00:05:21 +0000
+X-Dgit-Generated: 2.14-3.1 d03314ddf945eda65d2cc27e1518dcb4786faeca
+Subject: Remove updated timestamps from grub.texi and grub-dev.texi
+
+The timestamps are embedded in the documentation at build time, which
+does not accurately reflect when the documentation was last updated,
+and obviously causes issues for reproducible builds to embed the build
+time.
+
+https://reproducible-builds.org/docs/timestamps/
+
+---
+
+diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi
+index 51a0923ec..bbd54b7d6 100644
+--- a/docs/grub-dev.texi
++++ b/docs/grub-dev.texi
+@@ -17,8 +17,7 @@
+ @finalout
+
+ @copying
+-This developer manual is for GNU GRUB (version @value{VERSION},
+-@value{UPDATED}).
++This developer manual is for GNU GRUB (version @value{VERSION}).
+
+ Copyright @copyright{} 1999,2000,2001,2002,2004,2005,2006,2008,2009,2010,2011 Free Software Foundation, Inc.
+
+@@ -40,7 +39,7 @@ Invariant Sections.
+ @titlepage
+ @sp 10
+ @title the GNU GRUB developer manual
+-@subtitle The GRand Unified Bootloader, version @value{VERSION}, @value{UPDATED}.
++@subtitle The GRand Unified Bootloader, version @value{VERSION}.
+ @author Yoshinori K. Okuji
+ @author Colin D Bennett
+ @author Vesa Jääskeläinen
+diff --git a/docs/grub.texi b/docs/grub.texi
+index 78b530833..79f200e75 100644
+--- a/docs/grub.texi
++++ b/docs/grub.texi
+@@ -17,8 +17,7 @@
+ @finalout
+
+ @copying
+-This manual is for GNU GRUB (version @value{VERSION},
+-@value{UPDATED}).
++This manual is for GNU GRUB (version @value{VERSION}).
+
+ Copyright @copyright{} 1999,2000,2001,2002,2004,2006,2008,2009,2010,2011,2012,2013 Free Software Foundation, Inc.
+
+@@ -48,7 +47,7 @@ Invariant Sections.
+ @titlepage
+ @sp 10
+ @title the GNU GRUB manual
+-@subtitle The GRand Unified Bootloader, version @value{VERSION}, @value{UPDATED}.
++@subtitle The GRand Unified Bootloader, version @value{VERSION}.
+ @author Gordon Matzigkeit
+ @author Yoshinori K. Okuji
+ @author Colin Watson
diff -Nru grub2-2.14/debian/patches/series grub2-2.14/debian/patches/series
--- grub2-2.14/debian/patches/series	2026-06-23 07:54:03.000000000 -0700
+++ grub2-2.14/debian/patches/series	2026-07-16 11:45:44.000000000 -0700
@@ -69,3 +69,5 @@
 grub-install-removable-shim.patch
 upstream/efi-chainloader-set-loaded-image-device-path.patch
 upstream/efi-linux-set-loaded-image-device-path.patch
+remove-updated-timestamps-from-grub.texi.patch
+bug787795-grub2-please-build-rescue-iso-.patch
diff -Nru grub2-2.14/debian/platform-subst grub2-2.14/debian/platform-subst
--- grub2-2.14/debian/platform-subst	2026-06-19 07:19:05.000000000 -0700
+++ grub2-2.14/debian/platform-subst	2026-07-16 11:45:44.000000000 -0700
@@ -14,9 +14,10 @@
 my $grub_dir_path = "debian/tmp-$package/usr/lib/grub";
 opendir my $grub_dir, $grub_dir_path or die "can't opendir $grub_dir_path: $!";
 my @cpu_platforms = grep { !/^\./ } readdir $grub_dir;
+my @cpu_platforms_sorted = sort @cpu_platforms;
 closedir $grub_dir;

-$subst{FIRST_CPU_PLATFORM} = $cpu_platforms[0];
+$subst{FIRST_CPU_PLATFORM} = $cpu_platforms_sorted[0];

 sub emit ($) {
 	my $line = shift;
diff -Nru grub2-2.14/debian/rules grub2-2.14/debian/rules
--- grub2-2.14/debian/rules	2026-06-19 07:19:05.000000000 -0700
+++ grub2-2.14/debian/rules	2026-07-16 11:45:44.000000000 -0700
@@ -29,6 +29,7 @@
 export HOST_LDFLAGS
 export TARGET_CPPFLAGS := -Wno-unused-but-set-variable
 export TARGET_LDFLAGS := -no-pie
+export LC_ALL=C.UTF-8

 # upstream changed the tests to hard errors instead of skips when not running as root, so mark them
 # as expected failure.
@@ -52,6 +53,7 @@
 confflags = \
 	PACKAGE_VERSION="$(deb_version)" PACKAGE_STRING="GRUB $(deb_version)" \
 	CC=$(CC) TARGET_CC=$(CC) \
+	SHELL=/bin/bash \
 	--libdir=\$${prefix}/lib --libexecdir=\$${prefix}/lib \
 	--enable-grub-mkfont \
 	--disable-grub-emu-usb \
@@ -439,10 +441,10 @@
 	mkdir -p debian/$(package_bin)/usr/share/lintian/overrides
 	echo "$(package_bin): unstripped-binary-or-object [*.mod]" \
 		>> debian/$(package_bin)/usr/share/lintian/overrides/$(package_bin)
-	cd debian/tmp-$(package) && find usr/lib/grub -name kernel.img \
+	cd debian/tmp-$(package) && find usr/lib/grub -name kernel.img | sort \
 		| sed -e "s%.*%$(package_bin): statically-linked-binary [&]%g" \
 	>> $(CURDIR)/debian/$(package_bin)/usr/share/lintian/overrides/$(package_bin)
-	cd debian/tmp-$(package) && find usr/lib/grub -name kernel.img \
+	cd debian/tmp-$(package) && find usr/lib/grub -name kernel.img | sort \
 		| sed -e "s%.*%$(package_bin): unstripped-binary-or-object [&]%g" \
 	>> $(CURDIR)/debian/$(package_bin)/usr/share/lintian/overrides/$(package_bin)
 	if ([ "$@" = "install/grub-efi-amd64" ] && [ "$(DEB_HOST_ARCH_CPU)" = "i386" ]) || \
@@ -450,7 +452,7 @@
 	   [ "$@" = "install/grub-xen" ]; then \
 		echo "$(package_bin): binary-from-other-architecture [*.mod]" \
 			>> debian/$(package_bin)/usr/share/lintian/overrides/$(package_bin) ; \
-		cd debian/tmp-$(package) && find usr/lib/grub -name kernel.img \
+		cd debian/tmp-$(package) && find usr/lib/grub -name kernel.img | sort \
 			| sed -e "s%.*%$(package_bin): binary-from-other-architecture [&]%g" \
 		>> $(CURDIR)/debian/$(package_bin)/usr/share/lintian/overrides/$(package_bin) ; \
 	fi
@@ -482,7 +484,7 @@
 		>> debian/$(package_dbg)/usr/share/lintian/overrides/$(package_dbg)
 	echo "$(package_dbg): statically-linked-binary [*.image]" \
 		>> debian/$(package_dbg)/usr/share/lintian/overrides/$(package_dbg)
-	cd debian/tmp-$(package) && find usr/lib/grub -name kernel.exec \
+	cd debian/tmp-$(package) && find usr/lib/grub -name kernel.exec | sort \
 		| sed -e "s%.*%$(package_dbg): statically-linked-binary [&]%g" \
 	>> $(CURDIR)/debian/$(package_dbg)/usr/share/lintian/overrides/$(package_dbg)
 	if ([ "$@" = "install/grub-efi-amd64" ] && [ "$(DEB_HOST_ARCH_CPU)" = "i386" ]) || \
@@ -490,7 +492,7 @@
 	   [ "$@" = "install/grub-xen" ] ; then \
 		echo "$(package_dbg): binary-from-other-architecture [*.module]" \
 			>> debian/$(package_dbg)/usr/share/lintian/overrides/$(package_dbg) ; \
-		cd debian/tmp-$(package) && find usr/lib/grub -name kernel.exec \
+		cd debian/tmp-$(package) && find usr/lib/grub -name kernel.exec | sort \
 			| sed -e "s%.*%$(package_dbg): binary-from-other-architecture [&]%g" \
 		>> $(CURDIR)/debian/$(package_dbg)/usr/share/lintian/overrides/$(package_dbg) ; \
 	fi


live well,
  vagrant