Skip to content

Commit

Permalink
elf2flt.c: add support for SOURCE_DATE_EPOCH
Browse files Browse the repository at this point in the history
The bFLT header has a "build_date" field which contains the date/time
at which the bFLT file was created. Unfortunately, this breaks
reproducible builds as two identical builds done at different times
will produce different results.

For example, on a bFLT binary, diffoscope reports the following
change:

  00000000: 6246 4c54 0000 0004 0000 0045 0001 48d4  bFLT.......E..H.
  00000010: 0002 85a0 0002 fe50 0000 1000 0002 85a0  .......P........
 -00000020: 0000 0757 0000 0001 5e05 742e 0000 0000  ...W....^.t.....
 +00000020: 0000 0757 0000 0001 5e05 a5c2 0000 0000  ...W....^.......

In order to address this, this commit adds support for the
SOURCE_DATE_EPOCH environment variable, which is standardized by the
reproducible-builds.org group at
https://reproducible-builds.org/specs/source-date-epoch/.

We simply use the time from the SOURCE_DATE_EPOCH variable (which
contains the number of seconds since Epoch) when SOURCE_DATE_EPOCH is
available in the environment, and otherwise fallback to the existing
logic that takes the current time using time().

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
  • Loading branch information
tpetazzoni authored and vapier committed Dec 29, 2019
1 parent 1c9b454 commit 453398f
Showing 1 changed file with 27 additions and 1 deletion.
28 changes: 27 additions & 1 deletion elf2flt.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include <unistd.h> /* Userland prototypes of the Unix std system calls */
#include <fcntl.h> /* Flag value for file handling functions */
#include <time.h>
#include <errno.h>

/* from $(INSTALLDIR)/include */
#include <bfd.h> /* Main header file for the BFD library */
Expand Down Expand Up @@ -1689,6 +1690,31 @@ static void write_zeroes (unsigned long num, stream *stream)
}


static time_t get_build_date(void)
{
const char *sde;
unsigned long long epoch;
char *endptr;

sde = getenv("SOURCE_DATE_EPOCH");
if (!sde)
return time(NULL);

/* Largely inspired from
https://reproducible-builds.org/docs/source-date-epoch/ */
errno = 0;
epoch = strtoull(sde, &endptr, 10);
if ((errno == ERANGE && (epoch == ULLONG_MAX || epoch == 0))
|| (errno != 0 && epoch == 0)
|| (endptr == sde)
|| (*endptr != '\0')
|| (epoch > ULONG_MAX))
fatal("Invalid SOURCE_DATE_EPOCH value");

return (time_t)epoch;
}


int main(int argc, char *argv[])
{
int fd;
Expand Down Expand Up @@ -1948,7 +1974,7 @@ int main(int argc, char *argv[])
| (pic_with_got ? FLAT_FLAG_GOTPIC : 0)
| (docompress ? (docompress == 2 ? FLAT_FLAG_GZDATA : FLAT_FLAG_GZIP) : 0)
);
hdr.build_date = htonl((uint32_t)time(NULL));
hdr.build_date = htonl((uint32_t)get_build_date());
memset(hdr.filler, 0x00, sizeof(hdr.filler));

for (i=0; i<reloc_len; i++) reloc[i] = htonl(reloc[i]);
Expand Down

0 comments on commit 453398f

Please sign in to comment.