Skip to content

Instantly share code, notes, and snippets.

/72928.diff Secret
Created Sep 5, 2016

Embed
What would you like to do?
Patch for 72928
commit 19484ab77466f99c78fc0e677f7e03da0584d6a2
Author: Stanislav Malyshev <stas@php.net>
Date: Sun Sep 4 22:07:35 2016 -0700
Fix bug #72928 - Out of bound when verify signature of zip phar in phar_parse_zipfile
diff --git a/ext/phar/tests/bug72928.phpt b/ext/phar/tests/bug72928.phpt
new file mode 100644
index 0000000..8e6a954
--- /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
new file mode 100644
index 0000000..c480c5f
Binary files /dev/null and b/ext/phar/tests/bug72928.zip differ
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
@@ -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 2f1d915..b30e7e2 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");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.