This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] Reproducible PE timestamps


Hi,

--no-insert-timestamp was added to ld so that PE binaries can be built
reproducibly (with no timestamp), but it has the unfortunate side-effect of
causing crashes if binaries are bound to non-timestamped DLLs which are later
updated. (See https://sourceware.org/bugzilla/show_bug.cgi?id=16887 for
details.)

It occurred to me that one way of satisfying the various use cases without
breaking anything is to allow the timestamp to be set: that way, builds can
be reproduced, but as long as changes to DLLs cause a change in the
timestamp, then bound executables will be OK too. The following is a first
stab at this; it allows a timestamp to be given as a value to
--insert-timestamp. As far as I'm concerned the patch still needs
error-handling, the optarg processing should probably be extracted as a
separate function, and it needs documentation too. I'm also wondering whether
using "%s" with strptime is acceptable, since that's a GNU extension; would
it be worth pulling in the standard FSF parse-datetime.y?

Regards,

Stephen


diff --git a/bfd/libcoff-in.h b/bfd/libcoff-in.h
index 34e71a8..8558728 100644
--- a/bfd/libcoff-in.h
+++ b/bfd/libcoff-in.h
@@ -124,7 +124,7 @@ typedef struct pe_tdata
   int dll;
   int has_reloc_section;
   int dont_strip_reloc;
-  bfd_boolean insert_timestamp;
+  time_t insert_timestamp;
   bfd_boolean (*in_reloc_p) (bfd *, reloc_howto_type *);
   flagword real_flags;
 
diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index c897c64..1f4e785 100644
--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -877,7 +877,7 @@ _bfd_XXi_only_swap_filehdr_out (bfd * abfd, void * in, void * out)
 
   /* Only use a real timestamp if the option was chosen.  */
   if ((pe_data (abfd)->insert_timestamp))
-    H_PUT_32 (abfd, time (0), filehdr_out->f_timdat);
+    H_PUT_32 (abfd, pe_data (abfd)->insert_timestamp, filehdr_out->f_timdat);
 
   PUT_FILEHDR_SYMPTR (abfd, filehdr_in->f_symptr,
 		      filehdr_out->f_symptr);
diff --git a/ld/emultempl/pe.em b/ld/emultempl/pe.em
index 60882ce..9310f36 100644
--- a/ld/emultempl/pe.em
+++ b/ld/emultempl/pe.em
@@ -83,6 +83,8 @@ fragment <<EOF
 #include "pe-dll.h"
 #include "safe-ctype.h"
 
+#include <time.h>
+
 /* Permit the emulation parameters to override the default section
    alignment by setting OVERRIDE_SECTION_ALIGNMENT.  FIXME: This makes
    it seem that include/coff/internal.h should not define
@@ -132,7 +134,7 @@ static int support_old_code = 0;
 static char * thumb_entry_symbol = NULL;
 static lang_assignment_statement_type *image_base_statement = 0;
 static unsigned short pe_dll_characteristics = 0;
-static bfd_boolean insert_timestamp = TRUE;
+static time_t insert_timestamp = 0;
 static const char *emit_build_id;
 
 #ifdef DLL_SUPPORT
@@ -307,7 +309,7 @@ gld${EMULATION_NAME}_add_options
      OPTION_USE_NUL_PREFIXED_IMPORT_TABLES},
     {"no-leading-underscore", no_argument, NULL, OPTION_NO_LEADING_UNDERSCORE},
     {"leading-underscore", no_argument, NULL, OPTION_LEADING_UNDERSCORE},
-    {"insert-timestamp", no_argument, NULL, OPTION_INSERT_TIMESTAMP},
+    {"insert-timestamp", optional_argument, NULL, OPTION_INSERT_TIMESTAMP},
     {"no-insert-timestamp", no_argument, NULL, OPTION_NO_INSERT_TIMESTAMP},
 #ifdef DLL_SUPPORT
     /* getopt allows abbreviations, so we do this to stop it
@@ -769,7 +771,15 @@ gld${EMULATION_NAME}_handle_option (int optc)
       pe_leading_underscore = 1;
       break;
     case OPTION_INSERT_TIMESTAMP:
-      insert_timestamp = TRUE;
+      if (optarg)
+	{
+	  struct tm tm;
+	  memset (&tm, 0, sizeof (struct tm));
+	  strptime (optarg, "%s", &tm);
+	  insert_timestamp = mktime (&tm);
+	}
+      else
+	insert_timestamp = time (0);
       break;
     case OPTION_NO_INSERT_TIMESTAMP:
       insert_timestamp = FALSE;
diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em
index d6de792..cf289a4 100644
--- a/ld/emultempl/pep.em
+++ b/ld/emultempl/pep.em
@@ -85,6 +85,8 @@ fragment <<EOF
 #include "pep-dll.h"
 #include "safe-ctype.h"
 
+#include <time.h>
+
 /* Permit the emulation parameters to override the default section
    alignment by setting OVERRIDE_SECTION_ALIGNMENT.  FIXME: This makes
    it seem that include/coff/internal.h should not define
@@ -147,7 +149,7 @@ static flagword real_flags = IMAGE_FILE_LARGE_ADDRESS_AWARE;
 static int support_old_code = 0;
 static lang_assignment_statement_type *image_base_statement = 0;
 static unsigned short pe_dll_characteristics = 0;
-static bfd_boolean insert_timestamp = TRUE;
+static time_t insert_timestamp = 0;
 static const char *emit_build_id;
 
 #ifdef DLL_SUPPORT
@@ -324,7 +326,7 @@ gld${EMULATION_NAME}_add_options
     {"no-bind", no_argument, NULL, OPTION_NO_BIND},
     {"wdmdriver", no_argument, NULL, OPTION_WDM_DRIVER},
     {"tsaware", no_argument, NULL, OPTION_TERMINAL_SERVER_AWARE},
-    {"insert-timestamp", no_argument, NULL, OPTION_INSERT_TIMESTAMP},
+    {"insert-timestamp", optional_argument, NULL, OPTION_INSERT_TIMESTAMP},
     {"no-insert-timestamp", no_argument, NULL, OPTION_NO_INSERT_TIMESTAMP},
     {"build-id", optional_argument, NULL, OPTION_BUILD_ID},
     {NULL, no_argument, NULL, 0}
@@ -725,7 +727,15 @@ gld${EMULATION_NAME}_handle_option (int optc)
       pep_leading_underscore = 1;
       break;
     case OPTION_INSERT_TIMESTAMP:
-      insert_timestamp = TRUE;
+      if (optarg)
+	{
+	  struct tm tm;
+	  memset (&tm, 0, sizeof (struct tm));
+	  strptime (optarg, "%s", &tm);
+	  insert_timestamp = mktime (&tm);
+	}
+      else
+	insert_timestamp = TRUE;
       break;
     case OPTION_NO_INSERT_TIMESTAMP:
       insert_timestamp = FALSE;
diff --git a/ld/pe-dll.c b/ld/pe-dll.c
index e3e1f1f..4af64de 100644
--- a/ld/pe-dll.c
+++ b/ld/pe-dll.c
@@ -1186,7 +1186,7 @@ fill_edata (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED)
   memset (edata_d, 0, edata_sz);
 
   if (pe_data (abfd)->insert_timestamp)
-    H_PUT_32 (abfd, time (0), edata_d + 4);
+    H_PUT_32 (abfd, pe_data (abfd)->insert_timestamp, edata_d + 4);
 
   if (pe_def_file->version_major != -1)
     {

Attachment: pgpmzM1o_Cyrj.pgp
Description: OpenPGP digital signature


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]