Backported from 5.6.26 by Remi. Binary diff dropped. From dd69327ad783ea93f1e0a9e358974c7b098f29cc Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sun, 4 Sep 2016 22:07:35 -0700 Subject: [PATCH] Fix bug #72928 - Out of bound when verify signature of zip phar in phar_parse_zipfile --- ext/phar/tests/bug72928.phpt | 18 ++++++++++++++++++ ext/phar/tests/bug72928.zip | Bin 0 -> 140 bytes ext/phar/util.c | 28 ++++++++++++++++++++++++++++ ext/phar/zip.c | 2 +- 4 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 ext/phar/tests/bug72928.phpt create mode 100644 ext/phar/tests/bug72928.zip diff --git a/ext/phar/util.c b/ext/phar/util.c index 4bbd867..828be8f 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -1657,6 +1657,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; @@ -1690,6 +1697,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; @@ -1731,6 +1745,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; @@ -1764,6 +1785,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 bf895e7..ed156a2 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -430,7 +430,7 @@ int phar_parse_zipfile(php_stream *fp, char *fname, int fname_len, char *alias, 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");