From f4264ebc6499b82f892cefb54c0e4a0e9642e1d9 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Mon, 30 Mar 2015 13:09:32 +0200 Subject: Fixed bug 64343 PharData::extractTo fails for tarball created by BSD tar Phar did not know about PAX style global/file headers. Skip them, to be able to read the contents of those archives. --- NEWS | 4 ++++ ext/phar/phar_internal.h | 2 ++ ext/phar/tar.c | 7 +++++++ ext/phar/tests/tar/bug64343.phpt | 16 ++++++++++++++++ ext/phar/tests/tar/files/bug64343.tar | Bin 0 -> 10240 bytes 5 files changed, 29 insertions(+) create mode 100644 ext/phar/tests/tar/bug64343.phpt create mode 100644 ext/phar/tests/tar/files/bug64343.tar diff --git a/NEWS b/NEWS index 5cda6a2814..1cbaff8f02 100644 --- a/NEWS +++ b/NEWS @@ -39,6 +39,10 @@ PHP NEWS . Fixed bug #67403 (Add signatureType to openssl_x509_parse). . Add a check for RAND_egd to allow compiling against LibreSSL (Leigh) +- Phar: + . Fixed bug 64343 (PharData::extractTo fails for tarball created by BSD tar). + (Mike) + - Postgres: . Fixed bug #68741 (Null pointer dereference) (CVE-2015-1352). (Laruence) diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 989e6346f7..c862c49dca 100644 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -140,6 +140,8 @@ #define TAR_SYMLINK '2' #define TAR_DIR '5' #define TAR_NEW '8' +#define TAR_GLOBAL_HDR 'g' +#define TAR_FILE_HDR 'x' #define PHAR_MUNG_PHP_SELF (1<<0) #define PHAR_MUNG_REQUEST_URI (1<<1) diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 56b2a0eedf..844c6b5419 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -255,6 +255,12 @@ int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, size = entry.uncompressed_filesize = entry.compressed_filesize = phar_tar_number(hdr->size, sizeof(hdr->size)); + /* skip global/file headers (pax) */ + if (!old && (hdr->typeflag == TAR_GLOBAL_HDR || hdr->typeflag == TAR_FILE_HDR)) { + size = (size+511)&~511; + goto next; + } + if (((!old && hdr->prefix[0] == 0) || old) && strlen(hdr->name) == sizeof(".phar/signature.bin")-1 && !strncmp(hdr->name, ".phar/signature.bin", sizeof(".phar/signature.bin")-1)) { off_t curloc; @@ -548,6 +554,7 @@ bail: size = (size+511)&~511; if (((hdr->typeflag == '\0') || (hdr->typeflag == TAR_FILE)) && size > 0) { +next: /* this is not good enough - seek succeeds even on truncated tars */ php_stream_seek(fp, size, SEEK_CUR); if ((uint)php_stream_tell(fp) > totalsize) { diff --git a/ext/phar/tests/tar/bug64343.phpt b/ext/phar/tests/tar/bug64343.phpt new file mode 100644 index 0000000000..ed4501dd6a --- /dev/null +++ b/ext/phar/tests/tar/bug64343.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #64343 (phar cannot open tars with pax headers) +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECT-- +Test +===DONE=== diff --git a/ext/phar/tests/tar/files/bug64343.tar b/ext/phar/tests/tar/files/bug64343.tar new file mode 100644 index 0000000000..2eeb2062ff Binary files /dev/null and b/ext/phar/tests/tar/files/bug64343.tar differ -- cgit v1.2.1