[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#783210: glibc: please make the package build reproducibly



Source: glibc
Version: 2.19-18
Severity: wishlist
Tags: patch
User: reproducible-builds@lists.alioth.debian.org
Usertags: timestamps fileordering umask username uname

Hi!

While working on the “reproducible builds” effort [1], we have noticed
that glibc could not be built reproducibly.

The attached patch addresses several issues:

1. The source tarball will now stay identical despite variations of
   the time of the build, user, group, umask and file ordering.
2. version-info.h currently captures the build time and the current
   kernel version. In the context of Debian this is not really useful
   and a new patch simply removes it. The behavior is now the same
   if built under Linux or not.
3. nscd uses the date and time of the build as a version marker. So a
   patch is added to allow the build date to be set externally. The date
   of the latest debian/changelog entry will be used instead of the
   current time for Debian.

Once applied, glibc can be built reproducibly in our current
experimental framework.

 [1]: https://wiki.debian.org/ReproducibleBuilds

-- 
Lunar                                .''`. 
lunar@debian.org                    : :Ⓐ  :  # apt-get install anarchism
                                    `. `'` 
                                      `-   
diff --git a/debian/changelog b/debian/changelog
index a06fc11..fbb6d32 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,18 @@
+glibc (2.19-18.0~reproducible1) UNRELEASED; urgency=low
+
+  * Make the package build reproducibly:
+    - any/local-reproducible-version-info.diff: new patch to remove build
+      system information and build date from version-info.h.
+    - any/unsubmitted-allow-to-set-build-date.diff: allow to set the
+      build date through an environment variable when running ./configure.
+      This is then used in nscd.
+    - Set the previously mentioned build date to the latest debian/changelog
+      entry.
+    - Create source tarball in a deterministic manner: adjust file
+      modification time, user, group, permissions, and file order.
+
+ -- Jérémy Bobbio <lunar@debian.org>  Thu, 23 Apr 2015 11:18:59 +0200
+
 glibc (2.19-18) unstable; urgency=medium
 
   [ Aurelien Jarno ]
diff --git a/debian/patches/any/local-reproducible-version-info.diff b/debian/patches/any/local-reproducible-version-info.diff
new file mode 100644
index 0000000..06012ea
--- /dev/null
+++ b/debian/patches/any/local-reproducible-version-info.diff
@@ -0,0 +1,49 @@
+To enable glibc to build reproducibly, we remove build system information
+and build date from version-info.h.
+
+diff --git a/csu/Makefile b/csu/Makefile
+index b5afea0..211c2e6 100644
+--- a/csu/Makefile
++++ b/csu/Makefile
+@@ -133,40 +133,7 @@ all-Banner-files = $(wildcard $(addsuffix /Banner,\
+ 						 $(sysdeps-srcdirs))))
+ $(objpfx)version-info.h: $(common-objpfx)config.make $(all-Banner-files)
+ 	$(make-target-directory)
+-	(case $(config-os) in \
+-	   linux*) version=`(printf '%s\n%s\n' \
+-				    '#include <linux/version.h>' \
+-				    UTS_RELEASE \
+-			     | $(CC) $(CPPFLAGS) -O -E -P - -DNOT_IN_libc=1 | \
+-			     sed -e 's/"\([^"]*\)".*/\1/p' -e d) 2>/dev/null`;\
+-		   if [ -z "$$version" ]; then \
+-		     version=`(printf '%s\n%s\n' \
+-				      '#include <linux/version.h>' \
+-				       LINUX_VERSION_CODE \
+-			       | $(CC) $(CPPFLAGS) -O -E -P - -DNOT_IN_libc=1 \
+-			       | sed -n -e '/^[123456789].*/p' \
+-			       | awk '{v=$$1; \
+-				       printf("%d.%d.%d\n", \
+-					      v/65535, v/256%256, v%256)}') \
+-				2>/dev/null`; \
+-		   fi; \
+-		   if [ -z "$$version" ]; then \
+-		     if [ -r /proc/version ]; then \
+-		       version=`sed 's/.*Linux version \([^ ]*\) .*/>>\1<</' \
+-				< /proc/version`; \
+-		     else \
+-		       version=`uname -r`; \
+-		     fi; \
+-		   fi; \
+-		   os=`uname -s 2> /dev/null`; \
+-		   if [ -z "$$os" ]; then \
+-		     os=Linux; \
+-		   fi; \
+-		   printf '"Compiled on a %s %s system on %s.\\n"\n' \
+-			  "$$os" "$$version" "`date +%Y-%m-%d`";; \
+-	   *) ;; \
+-	 esac; \
+-	 files="$(all-Banner-files)";				\
++	(files="$(all-Banner-files)";				\
+ 	 if test -n "$$files"; then				\
+ 	   printf '"Available extensions:\\n"\n';		\
+ 	   sed -e '/^#/d' -e 's/^[[:space:]]*/	/'		\
diff --git a/debian/patches/any/unsubmitted-allow-to-set-build-date.diff b/debian/patches/any/unsubmitted-allow-to-set-build-date.diff
new file mode 100644
index 0000000..df7662a
--- /dev/null
+++ b/debian/patches/any/unsubmitted-allow-to-set-build-date.diff
@@ -0,0 +1,75 @@
+nscd uses the date and time of the build as a version marker. In order to allow
+builds to be reproducible, we now allow the date to be set by the environment
+variable BUILD_DATE when running ./configure.
+
+diff --git a/config.h.in b/config.h.in
+index 40797e7..02ccb2d 100644
+--- a/config.h.in
++++ b/config.h.in
+@@ -246,3 +246,6 @@
+ #undef HAVE_MIPS_NAN2008
+ 
+ #endif
++
++/* Date and time of the build. */
++#undef BUILD_DATE
+diff --git a/configure.ac b/configure.ac
+index f3dd87d..aa0b30d 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -2173,6 +2173,11 @@ RELEASE=`sed -n -e 's/^#define RELEASE "\([^"]*\)"/\1/p' < $srcdir/version.h`
+ AC_SUBST(VERSION)
+ AC_SUBST(RELEASE)
+ 
++if "x$BUILD_DATE" = x; then
++	BUILD_DATE=`LC_ALL=C date -u '+%b %_d %Y %H:%M:%S'`
++fi
++AC_DEFINE_UNQUOTED([BUILD_DATE], ["$BUILD_DATE"], "Date and time of the build.")
++
+ AC_CONFIG_FILES([config.make Makefile])
+ AC_CONFIG_COMMANDS([default],[[
+ case $CONFIG_FILES in *config.make*)
+diff --git a/configure b/configure
+index fc023d0..b03be3f 100755
+--- a/configure
++++ b/configure
+@@ -7387,6 +7394,15 @@
+ 
+ 
+ 
++if "x$BUILD_DATE" = x; then
++	BUILD_DATE=`LC_ALL=C date -u '+%b %_d %Y %H:%M:%S'`
++fi
++
++cat >>confdefs.h <<_ACEOF
++#define BUILD_DATE "$BUILD_DATE"
++_ACEOF
++
++
+ ac_config_files="$ac_config_files config.make Makefile"
+ 
+ ac_config_commands="$ac_config_commands default"
+diff --git a/nscd/nscd_stat.c b/nscd/nscd_stat.c
+index 997ff46..1e75b84 100644
+--- a/nscd/nscd_stat.c
++++ b/nscd/nscd_stat.c
+@@ -28,6 +28,7 @@
+ #include <libintl.h>
+ 
+ #include "nscd.h"
++#include "config.h"
+ #include "dbg_log.h"
+ #include "selinux.h"
+ #ifdef HAVE_SELINUX
+@@ -37,7 +38,11 @@
+ 
+ 
+ /* We use this to make sure the receiver is the same.  */
++#ifdef BUILD_DATE
++static const char compilation[21] = BUILD_DATE;
++#else
+ static const char compilation[21] = __DATE__ " " __TIME__;
++#endif
+ 
+ /* Statistic data for one database.  */
+ struct dbstat
diff --git a/debian/patches/series b/debian/patches/series
index a5f9cac..5a95f62 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -272,3 +272,5 @@ any/cvs-getnetbyname.diff
 any/cvs-vfprintf.diff
 any/cvs-wscanf.diff
 any/cvs-ldconfig-aux-cache.diff
+any/local-reproducible-version-info.diff
+any/unsubmitted-allow-to-set-build-date.diff
diff --git a/debian/rules b/debian/rules
index 24167cd..e483a4e 100755
--- a/debian/rules
+++ b/debian/rules
@@ -58,6 +58,11 @@ DEB_SOURCE_PACKAGE := $(strip $(shell egrep '^Source: ' debian/control | cut -f
 DEB_VERSION := $(shell dpkg-parsechangelog | egrep '^Version:' | cut -f 2 -d ' ')
 GLIBC_VERSION = $(shell echo $(DEB_VERSION) | sed -e 's/.*://' -e 's/-.*//')
 
+DEB_BUILD_DATE := $(shell dpkg-parsechangelog -S Date)
+# this one will be picked by configure script
+BUILD_DATE = $(shell date -u +'%b %_d %Y %H:%M:%S' -d '$(DEB_BUILD_DATE)')
+export BUILD_DATE
+
 DEB_BUILDDIR ?= $(build-tree)/$(DEB_HOST_ARCH)-$(curpass)
 
 GLIBC_SOURCES = $(addprefix $(shell basename $(CURDIR))/, \
diff --git a/debian/rules.d/build.mk b/debian/rules.d/build.mk
index 4df383c..91b8cab 100644
--- a/debian/rules.d/build.mk
+++ b/debian/rules.d/build.mk
@@ -275,9 +275,17 @@ endif
 
 $(stamp)source: $(stamp)patch
 	mkdir -p $(build-tree)
-	tar -c -J -C .. \
-		-f $(build-tree)/glibc-$(GLIBC_VERSION).tar.xz \
-		$(GLIBC_SOURCES)
+	cd .. && \
+	       find $(GLIBC_SOURCES) -depth -newermt '$(DEB_BUILD_DATE)' \
+			-print0 | \
+               xargs -0r touch --no-dereference --date='$(DEB_BUILD_DATE)'
+	cd .. && \
+		find $(GLIBC_SOURCES) -print0 | \
+		LC_ALL=C sort -z | \
+		tar -c -J --null -T - --no-recursion \
+			--mode=go=rX,u+rw,a-s \
+			--owner=root --group=root --numeric-owner \
+			-f $(CURDIR)/$(build-tree)/glibc-$(GLIBC_VERSION).tar.xz
 	mkdir -p debian/glibc-source/usr/src/glibc
 	tar cf - --files-from debian/glibc-source.filelist \
 	  | tar -x -C debian/glibc-source/usr/src/glibc -f -

Attachment: signature.asc
Description: Digital signature


Reply to: