Skip to content

Commit 0bfb970

Browse files
smalyshevweltling
authored andcommitted
Fix bug #72928 - Out of bound when verify signature of zip phar in phar_parse_zipfile
(cherry picked from commit 19484ab)
1 parent 1b2007d commit 0bfb970

File tree

4 files changed

+47
-1
lines changed

4 files changed

+47
-1
lines changed

Diff for: ext/phar/tests/bug72928.phpt

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Phar: #72928 (Out of bound when verify signature of zip phar in phar_parse_zipfile)
3+
--SKIPIF--
4+
<?php if (!extension_loaded("phar")) die("skip"); ?>
5+
--FILE--
6+
<?php
7+
chdir(__DIR__);
8+
try {
9+
$phar = new PharData('bug72928.zip');
10+
var_dump($phar);
11+
} catch(UnexpectedValueException $e) {
12+
print $e->getMessage()."\n";
13+
}
14+
?>
15+
DONE
16+
--EXPECTF--
17+
phar error: signature cannot be read in zip-based phar "%sbug72928.zip"
18+
DONE

Diff for: ext/phar/tests/bug72928.zip

140 Bytes
Binary file not shown.

Diff for: ext/phar/util.c

+28
Original file line numberDiff line numberDiff line change
@@ -1609,6 +1609,13 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
16091609
unsigned char digest[64];
16101610
PHP_SHA512_CTX context;
16111611

1612+
if (sig_len < sizeof(digest)) {
1613+
if (error) {
1614+
spprintf(error, 0, "broken signature");
1615+
}
1616+
return FAILURE;
1617+
}
1618+
16121619
PHP_SHA512Init(&context);
16131620
read_len = end_of_phar;
16141621

@@ -1642,6 +1649,13 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
16421649
unsigned char digest[32];
16431650
PHP_SHA256_CTX context;
16441651

1652+
if (sig_len < sizeof(digest)) {
1653+
if (error) {
1654+
spprintf(error, 0, "broken signature");
1655+
}
1656+
return FAILURE;
1657+
}
1658+
16451659
PHP_SHA256Init(&context);
16461660
read_len = end_of_phar;
16471661

@@ -1683,6 +1697,13 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
16831697
unsigned char digest[20];
16841698
PHP_SHA1_CTX context;
16851699

1700+
if (sig_len < sizeof(digest)) {
1701+
if (error) {
1702+
spprintf(error, 0, "broken signature");
1703+
}
1704+
return FAILURE;
1705+
}
1706+
16861707
PHP_SHA1Init(&context);
16871708
read_len = end_of_phar;
16881709

@@ -1716,6 +1737,13 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ
17161737
unsigned char digest[16];
17171738
PHP_MD5_CTX context;
17181739

1740+
if (sig_len < sizeof(digest)) {
1741+
if (error) {
1742+
spprintf(error, 0, "broken signature");
1743+
}
1744+
return FAILURE;
1745+
}
1746+
17191747
PHP_MD5Init(&context);
17201748
read_len = end_of_phar;
17211749

Diff for: ext/phar/zip.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ int phar_parse_zipfile(php_stream *fp, char *fname, int fname_len, char *alias,
418418
php_stream_seek(fp, sizeof(phar_zip_file_header) + entry.header_offset + entry.filename_len + PHAR_GET_16(zipentry.extra_len), SEEK_SET);
419419
sig = (char *) emalloc(entry.uncompressed_filesize);
420420
read = php_stream_read(fp, sig, entry.uncompressed_filesize);
421-
if (read != entry.uncompressed_filesize) {
421+
if (read != entry.uncompressed_filesize || read <= 8) {
422422
php_stream_close(sigfile);
423423
efree(sig);
424424
PHAR_ZIP_FAIL("signature cannot be read");

0 commit comments

Comments
 (0)