Skip to content

Commit c283f53

Browse files
committed
Fix #73809: Phar Zip parse crash - mmap fail
Phar signatures practically are of limited size; for the MD5 and SHA hashes the size is fixed (at most 64 bytes for SHA512); for OpenSSL public keys there is no size limit in theory, but "64 KiB ought to be good enough for anybody". So we check for that limit, to avoid fatal errors due to out of memory conditions. Since it is neither possible to have the signature compressed in the ZIP archive, nor is it possible to manually add a signature via Phar, we use ZipArchive to create a suitable archive for the test on the fly. Closes GH-6474.
1 parent ecee3f1 commit c283f53

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ PHP NEWS
2424
. Fixed bug #80368 (OpenSSL extension fails to build against LibreSSL due to
2525
lack of OCB support). (Nikita)
2626

27+
- Phar:
28+
. Fixed bug #73809 (Phar Zip parse crash - mmap fail). (cmb)
29+
2730
- Phpdbg:
2831
. Fixed bug #76813 (Access violation near NULL on source operand). (cmb)
2932

ext/phar/tests/bug73809.phpt

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
--TEST--
2+
Bug #73809 (Phar Zip parse crash - mmap fail)
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('phar')) die('skip phar extension not available');
6+
if (!extension_loaded('zip')) die('skip zip extension not available');
7+
?>
8+
--FILE--
9+
<?php
10+
// create the ZIP to be tested
11+
$zip = new ZipArchive;
12+
$zip->open(__DIR__ . '/73809.zip', ZipArchive::CREATE);
13+
$zip->addFromString('73809.txt', 'yada yada');
14+
$zip->addFromString('.phar/signature.bin', str_repeat('*', 64 * 1024 + 1));
15+
$zip->setCompressionName('.phar/signature.bin', ZipArchive::CM_STORE);
16+
var_dump($zip->close());
17+
18+
try {
19+
$phar = new PharData(__DIR__ . '/73809.zip');
20+
} catch (Exception $ex) {
21+
echo $ex->getMessage(), PHP_EOL;
22+
}
23+
?>
24+
--CLEAN--
25+
<?php
26+
@unlink(__DIR__ . '/73809.zip');
27+
?>
28+
--EXPECTF--
29+
bool(true)
30+
phar error: signatures larger than 64 KiB are not supported in zip-based phar "%s"

ext/phar/zip.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -405,8 +405,13 @@ int phar_parse_zipfile(php_stream *fp, char *fname, size_t fname_len, char *alia
405405
char *sig;
406406
size_t sig_len;
407407

408-
php_stream_tell(fp);
409408
pefree(entry.filename, entry.is_persistent);
409+
410+
if (entry.uncompressed_filesize > 0x10000) {
411+
PHAR_ZIP_FAIL("signatures larger than 64 KiB are not supported");
412+
}
413+
414+
php_stream_tell(fp);
410415
sigfile = php_stream_fopen_tmpfile();
411416
if (!sigfile) {
412417
PHAR_ZIP_FAIL("couldn't open temporary file");

0 commit comments

Comments
 (0)