diff options
author | kientzle <kientzle@FreeBSD.org> | 2005-08-02 03:13:42 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2005-08-02 03:13:42 +0000 |
commit | eda3e2bd3733063ba67e59dd8d3670614a834618 (patch) | |
tree | 063305285bf9b978fc1cea9f4b4eccdac3291346 /lib | |
parent | bf7551aa876ecb203502b88763d953a2eb81cb0f (diff) | |
download | FreeBSD-src-eda3e2bd3733063ba67e59dd8d3670614a834618.zip FreeBSD-src-eda3e2bd3733063ba67e59dd8d3670614a834618.tar.gz |
When copying time values from the main entry header to be used in the
header of the pax extension entry, clip them to ustar limits. In particular,
this prevents an internal panic for very old files.
Thanks to: Chris Spiegel
MFC after: 7 days
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libarchive/archive_write_set_format_pax.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/lib/libarchive/archive_write_set_format_pax.c b/lib/libarchive/archive_write_set_format_pax.c index 479cca6..60288eb 100644 --- a/lib/libarchive/archive_write_set_format_pax.c +++ b/lib/libarchive/archive_write_set_format_pax.c @@ -636,6 +636,8 @@ archive_write_pax_header(struct archive *a, if (archive_strlen(&(pax->pax_header)) > 0) { struct stat st; struct archive_entry *pax_attr_entry; + time_t s; + long ns; memset(&st, 0, sizeof(st)); pax_attr_entry = archive_entry_new(); @@ -668,16 +670,23 @@ archive_write_pax_header(struct archive *a, archive_entry_uname(entry_main)); archive_entry_set_gname(pax_attr_entry, archive_entry_gname(entry_main)); - /* Copy timestamps. */ - archive_entry_set_mtime(pax_attr_entry, - archive_entry_mtime(entry_main), - archive_entry_mtime_nsec(entry_main)); - archive_entry_set_atime(pax_attr_entry, - archive_entry_atime(entry_main), - archive_entry_atime_nsec(entry_main)); - archive_entry_set_ctime(pax_attr_entry, - archive_entry_ctime(entry_main), - archive_entry_ctime_nsec(entry_main)); + + /* Copy mtime, but clip to ustar limits. */ + s = archive_entry_mtime(entry_main); + ns = archive_entry_mtime_nsec(entry_main); + if (s < 0) { s = 0; ns = 0; } + if (s > 0x7fffffff) { s = 0x7fffffff; ns = 0; } + archive_entry_set_mtime(pax_attr_entry, s, ns); + + /* Ditto for atime. */ + s = archive_entry_atime(entry_main); + ns = archive_entry_atime_nsec(entry_main); + if (s < 0) { s = 0; ns = 0; } + if (s > 0x7fffffff) { s = 0x7fffffff; ns = 0; } + archive_entry_set_atime(pax_attr_entry, s, ns); + + /* Standard ustar doesn't support ctime. */ + archive_entry_set_ctime(pax_attr_entry, 0, 0); ret = __archive_write_format_header_ustar(a, paxbuff, pax_attr_entry, 'x', 1); |