浏览代码

dpkg-deb: Use new GNU tar --clamp-mtime option

This will guarantee that no file in binary packages has an mtime later
than the specified time. Which will be required to make binary packages
reproducible.

The option was officially added in GNU tar 1.29, but in Debian it was
introduced as a vendor patch in 1.28, so on Debian we depend on the
latter instead of the former version.

Closes: #759886
Guillem Jover 10 年之前
父节点
当前提交
62a638211c
共有 3 个文件被更改,包括 18 次插入4 次删除
  1. 2 0
      debian/changelog
  2. 1 1
      debian/control
  3. 15 3
      dpkg-deb/build.c

+ 2 - 0
debian/changelog

@@ -27,6 +27,8 @@ dpkg (1.18.8) UNRELEASED; urgency=medium
     was obviously wrong. Reported by Helmut Grohne <helmut@subdivi.de>.
     was obviously wrong. Reported by Helmut Grohne <helmut@subdivi.de>.
   * Fix strtol() errno check when parsing the COLUMNS envvar in dpkg-query.
   * Fix strtol() errno check when parsing the COLUMNS envvar in dpkg-query.
     Thanks to Sven Joachim <svenjoac@gmx.de>. Closes: #827265
     Thanks to Sven Joachim <svenjoac@gmx.de>. Closes: #827265
+  * Use new GNU tar --clamp-mtime option in dpkg-deb to make sure no file in
+    binary packages has an mtime later than the given time. Closes: #759886
   * Perl modules:
   * Perl modules:
     - Use warnings::warnif() instead of carp() for deprecated warnings.
     - Use warnings::warnif() instead of carp() for deprecated warnings.
     - Add new format_range() method and deprecate dpkg() and rfc822() methods
     - Add new format_range() method and deprecate dpkg() and rfc822() methods

+ 1 - 1
debian/control

@@ -35,7 +35,7 @@ Architecture: any
 Multi-Arch: foreign
 Multi-Arch: foreign
 Essential: yes
 Essential: yes
 Pre-Depends: ${shlibs:Depends}, tar (>= 1.23)
 Pre-Depends: ${shlibs:Depends}, tar (>= 1.23)
-Depends: ${misc:Depends}
+Depends: ${misc:Depends}, tar (>= 1.28-1)
 Breaks: dpkg-dev (<< 1.15.8), libdpkg-perl (<< 1.15.8)
 Breaks: dpkg-dev (<< 1.15.8), libdpkg-perl (<< 1.15.8)
 Suggests: apt
 Suggests: apt
 Replaces: manpages-it (<< 2.80-4)
 Replaces: manpages-it (<< 2.80-4)

+ 15 - 3
dpkg-deb/build.c

@@ -30,6 +30,7 @@
 #include <errno.h>
 #include <errno.h>
 #include <limits.h>
 #include <limits.h>
 #include <string.h>
 #include <string.h>
+#include <time.h>
 #include <dirent.h>
 #include <dirent.h>
 #include <fcntl.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <unistd.h>
@@ -420,6 +421,7 @@ typedef void filenames_feed_func(const char *dir, int fd_out);
  */
  */
 static void
 static void
 tarball_pack(const char *dir, filenames_feed_func *tar_filenames_feeder,
 tarball_pack(const char *dir, filenames_feed_func *tar_filenames_feeder,
+             time_t timestamp,
              struct compress_params *tar_compress_params, int fd_out)
              struct compress_params *tar_compress_params, int fd_out)
 {
 {
   int pipe_filenames[2], pipe_tarball[2];
   int pipe_filenames[2], pipe_tarball[2];
@@ -430,6 +432,8 @@ tarball_pack(const char *dir, filenames_feed_func *tar_filenames_feeder,
   m_pipe(pipe_tarball);
   m_pipe(pipe_tarball);
   pid_tar = subproc_fork();
   pid_tar = subproc_fork();
   if (pid_tar == 0) {
   if (pid_tar == 0) {
+    char mtime[50];
+
     m_dup2(pipe_filenames[0], 0);
     m_dup2(pipe_filenames[0], 0);
     close(pipe_filenames[0]);
     close(pipe_filenames[0]);
     close(pipe_filenames[1]);
     close(pipe_filenames[1]);
@@ -440,7 +444,11 @@ tarball_pack(const char *dir, filenames_feed_func *tar_filenames_feeder,
     if (chdir(dir))
     if (chdir(dir))
       ohshite(_("failed to chdir to '%.255s'"), dir);
       ohshite(_("failed to chdir to '%.255s'"), dir);
 
 
-    execlp(TAR, "tar", "-cf", "-", "--format=gnu", "--null", "--no-unquote",
+    snprintf(mtime, sizeof(mtime), "@%ld", timestamp);
+
+    execlp(TAR, "tar", "-cf", "-", "--format=gnu",
+                       "--mtime", mtime, "--clamp-mtime",
+                       "--null", "--no-unquote",
                        "--no-recursion", "-T", "-", NULL);
                        "--no-recursion", "-T", "-", NULL);
     ohshite(_("unable to execute %s (%s)"), "tar -cf", TAR);
     ohshite(_("unable to execute %s (%s)"), "tar -cf", TAR);
   }
   }
@@ -475,6 +483,7 @@ do_build(const char *const *argv)
   struct compress_params control_compress_params;
   struct compress_params control_compress_params;
   struct dpkg_error err;
   struct dpkg_error err;
   struct dpkg_ar *ar;
   struct dpkg_ar *ar;
+  time_t timestamp;
   const char *dir, *dest;
   const char *dir, *dest;
   char *ctrldir;
   char *ctrldir;
   char *debar;
   char *debar;
@@ -509,6 +518,8 @@ do_build(const char *const *argv)
   }
   }
   m_output(stdout, _("<standard output>"));
   m_output(stdout, _("<standard output>"));
 
 
+  timestamp = time(NULL);
+
   /* Now that we have verified everything its time to actually
   /* Now that we have verified everything its time to actually
    * build something. Let's start by making the ar-wrapper. */
    * build something. Let's start by making the ar-wrapper. */
   ar = dpkg_ar_create(debar, 0644);
   ar = dpkg_ar_create(debar, 0644);
@@ -539,7 +550,8 @@ do_build(const char *const *argv)
   }
   }
 
 
   /* Fork a tar to package the control-section of the package. */
   /* Fork a tar to package the control-section of the package. */
-  tarball_pack(ctrldir, control_treewalk_feed, &control_compress_params, gzfd);
+  tarball_pack(ctrldir, control_treewalk_feed, timestamp,
+               &control_compress_params, gzfd);
 
 
   free(ctrldir);
   free(ctrldir);
 
 
@@ -600,7 +612,7 @@ do_build(const char *const *argv)
   }
   }
 
 
   /* Pack the directory into a tarball, feeding files from the callback. */
   /* Pack the directory into a tarball, feeding files from the callback. */
-  tarball_pack(dir, file_treewalk_feed, &compress_params, gzfd);
+  tarball_pack(dir, file_treewalk_feed, timestamp, &compress_params, gzfd);
 
 
   /* Okay, we have data.tar as well now, add it to the ar wrapper. */
   /* Okay, we have data.tar as well now, add it to the ar wrapper. */
   if (deb_format.major == 2) {
   if (deb_format.major == 2) {