diff options
author | Stanislav Malyshev <stas@php.net> | 2016-09-04 22:07:35 -0700 |
---|---|---|
committer | Ferenc Kovacs <tyra3l@gmail.com> | 2016-09-15 10:02:52 +0200 |
commit | dd69327ad783ea93f1e0a9e358974c7b098f29cc (patch) | |
tree | 4195a4031540fc2a4addfec779df78d3ecd8a4e1 | |
parent | 120eb29bb350950213bbc9a0e11345ba20b63db0 (diff) | |
download | php-git-dd69327ad783ea93f1e0a9e358974c7b098f29cc.tar.gz |
Fix bug #72928 - Out of bound when verify signature of zip phar in phar_parse_zipfile
-rw-r--r-- | ext/phar/tests/bug72928.phpt | 18 | ||||
-rw-r--r-- | ext/phar/tests/bug72928.zip | bin | 0 -> 140 bytes | |||
-rw-r--r-- | ext/phar/util.c | 28 | ||||
-rw-r--r-- | ext/phar/zip.c | 2 |
4 files changed, 47 insertions, 1 deletions
diff --git a/ext/phar/tests/bug72928.phpt b/ext/phar/tests/bug72928.phpt new file mode 100644 index 0000000000..8e6a95418c --- /dev/null +++ b/ext/phar/tests/bug72928.phpt @@ -0,0 +1,18 @@ +--TEST-- +Phar: #72928 (Out of bound when verify signature of zip phar in phar_parse_zipfile) +--SKIPIF-- +<?php if (!extension_loaded("phar")) die("skip"); ?> +--FILE-- +<?php +chdir(__DIR__); +try { +$phar = new PharData('bug72928.zip'); +var_dump($phar); +} catch(UnexpectedValueException $e) { + print $e->getMessage()."\n"; +} +?> +DONE +--EXPECTF-- +phar error: signature cannot be read in zip-based phar "%sbug72928.zip" +DONE
\ No newline at end of file diff --git a/ext/phar/tests/bug72928.zip b/ext/phar/tests/bug72928.zip Binary files differnew file mode 100644 index 0000000000..c480c5f537 --- /dev/null +++ b/ext/phar/tests/bug72928.zip diff --git a/ext/phar/util.c b/ext/phar/util.c index 4bbd8676cb..828be8f9a2 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -1650,6 +1650,13 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ unsigned char digest[64]; PHP_SHA512_CTX context; + if (sig_len < sizeof(digest)) { + if (error) { + spprintf(error, 0, "broken signature"); + } + return FAILURE; + } + PHP_SHA512Init(&context); read_len = end_of_phar; @@ -1683,6 +1690,13 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ unsigned char digest[32]; PHP_SHA256_CTX context; + if (sig_len < sizeof(digest)) { + if (error) { + spprintf(error, 0, "broken signature"); + } + return FAILURE; + } + PHP_SHA256Init(&context); read_len = end_of_phar; @@ -1724,6 +1738,13 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ unsigned char digest[20]; PHP_SHA1_CTX context; + if (sig_len < sizeof(digest)) { + if (error) { + spprintf(error, 0, "broken signature"); + } + return FAILURE; + } + PHP_SHA1Init(&context); read_len = end_of_phar; @@ -1757,6 +1778,13 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ unsigned char digest[16]; PHP_MD5_CTX context; + if (sig_len < sizeof(digest)) { + if (error) { + spprintf(error, 0, "broken signature"); + } + return FAILURE; + } + PHP_MD5Init(&context); read_len = end_of_phar; diff --git a/ext/phar/zip.c b/ext/phar/zip.c index bf895e7dfe..ed156a2d00 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -430,7 +430,7 @@ foundit: php_stream_seek(fp, sizeof(phar_zip_file_header) + entry.header_offset + entry.filename_len + PHAR_GET_16(zipentry.extra_len), SEEK_SET); sig = (char *) emalloc(entry.uncompressed_filesize); read = php_stream_read(fp, sig, entry.uncompressed_filesize); - if (read != entry.uncompressed_filesize) { + if (read != entry.uncompressed_filesize || read <= 8) { php_stream_close(sigfile); efree(sig); PHAR_ZIP_FAIL("signature cannot be read"); |