From 4fdfd1f62a9d50298b0bb71e8bea04174af4a3ab Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Wed, 24 Jul 2019 13:36:50 +0200 Subject: Fix processing of tar mtime on 32 bit systems struct stat uses time_t to store time values. On some 32 bit systems, this may be a 32 bit integer. This patch adds a broken-out 64 bit time value to tar_header_decoded_t and makes sure to clamp the value to +/- (2^32 - 1) if required when writing it back to a struct stat. Reported-by: Matt Turner Signed-off-by: David Oberhollenzer --- lib/tar/read_header.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/tar/read_header.c b/lib/tar/read_header.c index 043b5ff..a083c2f 100644 --- a/lib/tar/read_header.c +++ b/lib/tar/read_header.c @@ -129,11 +129,11 @@ static int read_pax_header(int fd, uint64_t entsize, unsigned int *set_by_pax, if (line[6] == '-') { if (pax_read_decimal(line + 7, &field)) goto fail; - out->sb.st_mtime = -((int64_t)field); + out->mtime = -((int64_t)field); } else { if (pax_read_decimal(line + 6, &field)) goto fail; - out->sb.st_mtime = field; + out->mtime = field; } *set_by_pax |= PAX_MTIME; } else if (!strncmp(line, "GNU.sparse.name=", 16)) { @@ -284,9 +284,9 @@ static int decode_header(const tar_header_t *hdr, unsigned int set_by_pax, return -1; if (field & 0x8000000000000000UL) { field = ~field + 1; - out->sb.st_mtime = -((int64_t)field); + out->mtime = -((int64_t)field); } else { - out->sb.st_mtime = field; + out->mtime = field; } } @@ -338,6 +338,17 @@ static int decode_header(const tar_header_t *hdr, unsigned int set_by_pax, break; } +#if SIZEOF_TIME_T < 8 + if (out->mtime > (int64_t)INT32_MAX) { + out->sb.st_mtime = INT32_MAX; + } else if (out->mtime < (int64_t)INT32_MIN) { + out->sb.st_mtime = INT32_MIN; + } else { + out->sb.st_mtime = out->mtime; + } +#else + out->sb.st_mtime = out->mtime; +#endif return 0; } -- cgit v1.2.3