summaryrefslogtreecommitdiff
path: root/ext/phar
diff options
context:
space:
mode:
authorStanislav Malyshev <stas@php.net>2016-02-01 18:32:31 -0800
committerStanislav Malyshev <stas@php.net>2016-02-01 18:32:31 -0800
commit309ead112f64249594cccfa4b0303706d4097a0f (patch)
tree46775099a2d2e7784fad87aa12c72c60fddd47ff /ext/phar
parent2f1ce4f209925a81a07797e48238db711b10b695 (diff)
parentb5ef8ed168a7b84ca6e66676c28a290368b8777d (diff)
downloadphp-git-309ead112f64249594cccfa4b0303706d4097a0f.tar.gz
Merge branch 'PHP-5.5.32' into PHP-5.6.18
* PHP-5.5.32: Fixed bug #71488: Stack overflow when decompressing tar archives update NEWS add missing headers for SIZE_MAX backport the escapeshell* functions hardening branch add tests Fix bug #71459 - Integer overflow in iptcembed() Fixed bug #71323 - Output of stream_get_meta_data can be falsified by its input Fix bug #71391: NULL Pointer Dereference in phar_tar_setupmetadata() Fix bug #71335: Type Confusion in WDDX Packet Deserialization Fix bug #71354 - remove UMR when size is 0
Diffstat (limited to 'ext/phar')
-rw-r--r--ext/phar/phar_object.c1
-rw-r--r--ext/phar/tar.c25
-rw-r--r--ext/phar/tests/bug71354.phpt13
-rw-r--r--ext/phar/tests/bug71354.tarbin0 -> 1536 bytes
-rw-r--r--ext/phar/tests/bug71391.phpt18
-rw-r--r--ext/phar/tests/bug71391.tarbin0 -> 3584 bytes
-rw-r--r--ext/phar/tests/bug71488.phpt16
-rw-r--r--ext/phar/tests/bug71488.tarbin0 -> 10240 bytes
8 files changed, 67 insertions, 6 deletions
diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c
index 0fcef8d511..e02f9040e7 100644
--- a/ext/phar/phar_object.c
+++ b/ext/phar/phar_object.c
@@ -4886,6 +4886,7 @@ PHP_METHOD(PharFileInfo, getContent)
phar_seek_efp(link, 0, SEEK_SET, 0, 0 TSRMLS_CC);
Z_TYPE_P(return_value) = IS_STRING;
+ Z_STRVAL_P(return_value) = NULL;
Z_STRLEN_P(return_value) = php_stream_copy_to_mem(fp, &(Z_STRVAL_P(return_value)), link->uncompressed_filesize, 0);
if (!Z_STRVAL_P(return_value)) {
diff --git a/ext/phar/tar.c b/ext/phar/tar.c
index 5d121cb030..1fcfe52756 100644
--- a/ext/phar/tar.c
+++ b/ext/phar/tar.c
@@ -195,6 +195,13 @@ static int phar_tar_process_metadata(phar_entry_info *entry, php_stream *fp TSRM
}
/* }}} */
+#if !HAVE_STRNLEN
+static size_t strnlen(const char *s, size_t maxlen) {
+ char *r = (char *)memchr(s, '\0', maxlen);
+ return r ? r-s : maxlen;
+}
+#endif
+
int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, phar_archive_data** pphar, int is_data, php_uint32 compression, char **error TSRMLS_DC) /* {{{ */
{
char buf[512], *actual_alias = NULL, *p;
@@ -204,6 +211,7 @@ int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias,
php_uint32 sum1, sum2, size, old;
phar_archive_data *myphar, **actual;
int last_was_longlink = 0;
+ int linkname_len;
if (error) {
*error = NULL;
@@ -264,7 +272,7 @@ int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias,
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)) {
+ if (((!old && hdr->prefix[0] == 0) || old) && strnlen(hdr->name, 100) == sizeof(".phar/signature.bin")-1 && !strncmp(hdr->name, ".phar/signature.bin", sizeof(".phar/signature.bin")-1)) {
off_t curloc;
if (size > 511) {
@@ -474,20 +482,22 @@ bail:
}
entry.link = NULL;
-
+ /* link field is null-terminated unless it has 100 non-null chars.
+ * Thus we can not use strlen. */
+ linkname_len = strnlen(hdr->linkname, 100);
if (entry.tar_type == TAR_LINK) {
- if (!zend_hash_exists(&myphar->manifest, hdr->linkname, strlen(hdr->linkname))) {
+ if (!zend_hash_exists(&myphar->manifest, hdr->linkname, linkname_len)) {
if (error) {
- spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file - hard link to non-existent file \"%s\"", fname, hdr->linkname);
+ spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file - hard link to non-existent file \"%.*s\"", fname, linkname_len, hdr->linkname);
}
pefree(entry.filename, entry.is_persistent);
php_stream_close(fp);
phar_destroy_phar_data(myphar TSRMLS_CC);
return FAILURE;
}
- entry.link = estrdup(hdr->linkname);
+ entry.link = estrndup(hdr->linkname, linkname_len);
} else if (entry.tar_type == TAR_SYMLINK) {
- entry.link = estrdup(hdr->linkname);
+ entry.link = estrndup(hdr->linkname, linkname_len);
}
phar_set_inode(&entry TSRMLS_CC);
zend_hash_add(&myphar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), (void **) &newentry);
@@ -880,6 +890,9 @@ static int phar_tar_setupmetadata(void *pDest, void *argument TSRMLS_DC) /* {{{
if (entry->filename_len >= sizeof(".phar/.metadata") && !memcmp(entry->filename, ".phar/.metadata", sizeof(".phar/.metadata")-1)) {
if (entry->filename_len == sizeof(".phar/.metadata.bin")-1 && !memcmp(entry->filename, ".phar/.metadata.bin", sizeof(".phar/.metadata.bin")-1)) {
+ if (entry->phar->metadata == NULL) {
+ return ZEND_HASH_APPLY_REMOVE;
+ }
return phar_tar_setmetadata(entry->phar->metadata, entry, error TSRMLS_CC);
}
/* search for the file this metadata entry references */
diff --git a/ext/phar/tests/bug71354.phpt b/ext/phar/tests/bug71354.phpt
new file mode 100644
index 0000000000..43230f1520
--- /dev/null
+++ b/ext/phar/tests/bug71354.phpt
@@ -0,0 +1,13 @@
+--TEST--
+Phar: bug #71354: Heap corruption in tar/zip/phar parser.
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--FILE--
+<?php
+$p = new PharData(__DIR__."/bug71354.tar");
+var_dump($p['aaaa']->getContent());
+?>
+DONE
+--EXPECT--
+string(0) ""
+DONE \ No newline at end of file
diff --git a/ext/phar/tests/bug71354.tar b/ext/phar/tests/bug71354.tar
new file mode 100644
index 0000000000..b0bd992b9e
--- /dev/null
+++ b/ext/phar/tests/bug71354.tar
Binary files differ
diff --git a/ext/phar/tests/bug71391.phpt b/ext/phar/tests/bug71391.phpt
new file mode 100644
index 0000000000..b8d84f5375
--- /dev/null
+++ b/ext/phar/tests/bug71391.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Phar: bug #71391: NULL Pointer Dereference in phar_tar_setupmetadata()
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--FILE--
+<?php
+// duplicate since the tar will change
+copy(__DIR__."/bug71391.tar", __DIR__."/bug71391.test.tar");
+$p = new PharData(__DIR__."/bug71391.test.tar");
+$p->delMetaData();
+?>
+DONE
+--CLEAN--
+<?php
+unlink(__DIR__."/bug71391.test.tar");
+?>
+--EXPECT--
+DONE \ No newline at end of file
diff --git a/ext/phar/tests/bug71391.tar b/ext/phar/tests/bug71391.tar
new file mode 100644
index 0000000000..a5b155ac87
--- /dev/null
+++ b/ext/phar/tests/bug71391.tar
Binary files differ
diff --git a/ext/phar/tests/bug71488.phpt b/ext/phar/tests/bug71488.phpt
new file mode 100644
index 0000000000..05fdd8f481
--- /dev/null
+++ b/ext/phar/tests/bug71488.phpt
@@ -0,0 +1,16 @@
+--TEST--
+Phar: bug #71488: Stack overflow when decompressing tar archives
+--SKIPIF--
+<?php if (!extension_loaded("phar")) die("skip"); ?>
+--FILE--
+<?php
+$p = new PharData(__DIR__."/bug71488.tar");
+$newp = $p->decompress("test");
+?>
+DONE
+--CLEAN--
+<?php
+@unlink(__DIR__."/bug71488.test");
+?>
+--EXPECT--
+DONE \ No newline at end of file
diff --git a/ext/phar/tests/bug71488.tar b/ext/phar/tests/bug71488.tar
new file mode 100644
index 0000000000..6e14195025
--- /dev/null
+++ b/ext/phar/tests/bug71488.tar
Binary files differ