From: Thomas Petazzoni Date: Fri, 27 Dec 2019 15:40:42 +0000 (+0100) Subject: elf2flt.c: add support for SOURCE_DATE_EPOCH X-Git-Url: https://git.wh0rd.org/?a=commitdiff_plain;h=453398f917d167f8c308c8f997270c48ae8f8b12;p=elf2flt.git elf2flt.c: add support for SOURCE_DATE_EPOCH 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 --- diff --git a/elf2flt.c b/elf2flt.c index 8973cef..b7c4a49 100644 --- a/elf2flt.c +++ b/elf2flt.c @@ -46,6 +46,7 @@ #include /* Userland prototypes of the Unix std system calls */ #include /* Flag value for file handling functions */ #include +#include /* from $(INSTALLDIR)/include */ #include /* Main header file for the BFD library */ @@ -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; @@ -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