diff options
author | Stanislav Malyshev <stas@php.net> | 2018-12-03 00:42:55 -0800 |
---|---|---|
committer | Stanislav Malyshev <stas@php.net> | 2018-12-03 00:42:55 -0800 |
commit | 3d8d13f7b90960ab017f391a5ba21b805fbdbcc4 (patch) | |
tree | 9516864483d238d4d696bd30ebf2c834fe7c04e3 | |
parent | 1deee2ba7cfaa93f1d49d0394401138ce23f36c6 (diff) | |
parent | 8fff90250bebaef0ffbf37008358f4db5a68dd50 (diff) | |
download | php-git-3d8d13f7b90960ab017f391a5ba21b805fbdbcc4.tar.gz |
Merge branch 'PHP-7.2' into PHP-7.3
* PHP-7.2:
Fix bug #77143 - add more checks to buffer reads
Fix bug #77143 - add more checks to buffer reads
Fix #77020: null pointer dereference in imap_mail
Don't need interactive progress on git clones in Travis
Fix TSRM signature - php_stream_stat macro has it's own TSRM
Regenerate certificates for openssl tests
Improve test for bug77022
-rw-r--r-- | .travis.yml | 3 | ||||
-rw-r--r-- | ext/imap/php_imap.c | 1 | ||||
-rw-r--r-- | ext/imap/tests/bug77020.phpt | 15 | ||||
-rw-r--r-- | ext/phar/phar.c | 30 | ||||
-rw-r--r-- | ext/phar/tests/bug73768.phpt | 2 | ||||
-rw-r--r-- | ext/phar/tests/bug77022.phpt | 6 | ||||
-rw-r--r-- | ext/phar/tests/bug77143.phar | bin | 0 -> 50 bytes | |||
-rw-r--r-- | ext/phar/tests/bug77143.phpt | 18 |
8 files changed, 63 insertions, 12 deletions
diff --git a/.travis.yml b/.travis.yml index 702802ecf5..f7fddf68b3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,6 @@ +git: + quiet: true + dist: trusty language: c sudo: required diff --git a/ext/imap/php_imap.c b/ext/imap/php_imap.c index 9e626a4cfa..01d1a5f80c 100644 --- a/ext/imap/php_imap.c +++ b/ext/imap/php_imap.c @@ -4116,7 +4116,6 @@ PHP_FUNCTION(imap_mail) if (!ZSTR_LEN(message)) { /* this is not really an error, so it is allowed. */ php_error_docref(NULL, E_WARNING, "No message string in mail command"); - message = NULL; } if (_php_imap_mail(ZSTR_VAL(to), ZSTR_VAL(subject), ZSTR_VAL(message), headers?ZSTR_VAL(headers):NULL, cc?ZSTR_VAL(cc):NULL, diff --git a/ext/imap/tests/bug77020.phpt b/ext/imap/tests/bug77020.phpt new file mode 100644 index 0000000000..8a65232eec --- /dev/null +++ b/ext/imap/tests/bug77020.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #77020 (null pointer dereference in imap_mail) +--SKIPIF-- +<?php +if (!extension_loaded('imap')) die('skip imap extension not available'); +?> +--FILE-- +<?php +imap_mail('1', 1, NULL); +?> +===DONE=== +--EXPECTF-- +Warning: imap_mail(): No message string in mail command in %s on line %d +%s +===DONE=== diff --git a/ext/phar/phar.c b/ext/phar/phar.c index b3be34d84e..4d5988eaa9 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -641,6 +641,18 @@ int phar_parse_metadata(char **buffer, zval *metadata, uint32_t zip_metadata_len /* }}}*/ /** + * Size of fixed fields in the manifest. + * See: http://php.net/manual/en/phar.fileformat.phar.php + */ +#define MANIFEST_FIXED_LEN 18 + +#define SAFE_PHAR_GET_32(buffer, endbuffer, var) \ + if (UNEXPECTED(buffer + 4 > endbuffer)) { \ + MAPPHAR_FAIL("internal corruption of phar \"%s\" (truncated manifest header)"); \ + } \ + PHAR_GET_32(buffer, var); + +/** * Does not check for a previously opened phar in the cache. * * Parse a new one and add it to the cache, returning either SUCCESS or @@ -725,12 +737,12 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, size_t fname_len, ch savebuf = buffer; endbuffer = buffer + manifest_len; - if (manifest_len < 10 || manifest_len != php_stream_read(fp, buffer, manifest_len)) { + if (manifest_len < MANIFEST_FIXED_LEN || manifest_len != php_stream_read(fp, buffer, manifest_len)) { MAPPHAR_FAIL("internal corruption of phar \"%s\" (truncated manifest header)") } /* extract the number of entries */ - PHAR_GET_32(buffer, manifest_count); + SAFE_PHAR_GET_32(buffer, endbuffer, manifest_count); if (manifest_count == 0) { MAPPHAR_FAIL("in phar \"%s\", manifest claims to have zero entries. Phars must have at least 1 entry"); @@ -750,7 +762,7 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, size_t fname_len, ch return FAILURE; } - PHAR_GET_32(buffer, manifest_flags); + SAFE_PHAR_GET_32(buffer, endbuffer, manifest_flags); manifest_flags &= ~PHAR_HDR_COMPRESSION_MASK; manifest_flags &= ~PHAR_FILE_COMPRESSION_MASK; @@ -970,13 +982,13 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, size_t fname_len, ch } /* extract alias */ - PHAR_GET_32(buffer, tmp_len); + SAFE_PHAR_GET_32(buffer, endbuffer, tmp_len); if (buffer + tmp_len > endbuffer) { MAPPHAR_FAIL("internal corruption of phar \"%s\" (buffer overrun)"); } - if (manifest_len < 10 + tmp_len) { + if (manifest_len < MANIFEST_FIXED_LEN + tmp_len) { MAPPHAR_FAIL("internal corruption of phar \"%s\" (truncated manifest header)") } @@ -1014,7 +1026,7 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, size_t fname_len, ch } /* we have 5 32-bit items plus 1 byte at least */ - if (manifest_count > ((manifest_len - 10 - tmp_len) / (5 * 4 + 1))) { + if (manifest_count > ((manifest_len - MANIFEST_FIXED_LEN - tmp_len) / (5 * 4 + 1))) { /* prevent serious memory issues */ MAPPHAR_FAIL("internal corruption of phar \"%s\" (too many manifest entries for size of manifest)") } @@ -1023,12 +1035,12 @@ static int phar_parse_pharfile(php_stream *fp, char *fname, size_t fname_len, ch mydata->is_persistent = PHAR_G(persist); /* check whether we have meta data, zero check works regardless of byte order */ - PHAR_GET_32(buffer, len); + SAFE_PHAR_GET_32(buffer, endbuffer, len); if (mydata->is_persistent) { mydata->metadata_len = len; - if(!len) { + if (!len) { /* FIXME: not sure why this is needed but removing it breaks tests */ - PHAR_GET_32(buffer, len); + SAFE_PHAR_GET_32(buffer, endbuffer, len); } } if(len > (size_t)(endbuffer - buffer)) { diff --git a/ext/phar/tests/bug73768.phpt b/ext/phar/tests/bug73768.phpt index 37a4da0253..3062268b80 100644 --- a/ext/phar/tests/bug73768.phpt +++ b/ext/phar/tests/bug73768.phpt @@ -13,4 +13,4 @@ echo "OK\n"; } ?> --EXPECTF-- -cannot load phar "%sbug73768.phar" with implicit alias "" under different alias "alias.phar" +internal corruption of phar "%sbug73768.phar" (truncated manifest header) diff --git a/ext/phar/tests/bug77022.phpt b/ext/phar/tests/bug77022.phpt index 66bcf66dd4..c78d1bdafd 100644 --- a/ext/phar/tests/bug77022.phpt +++ b/ext/phar/tests/bug77022.phpt @@ -1,7 +1,10 @@ --TEST-- Phar: Bug #77022: PharData always creates new files with mode 0666 --SKIPIF-- -<?php if (!extension_loaded("phar")) die("skip"); ?> +<?php +if (!extension_loaded("phar")) die("skip"); +if (defined("PHP_WINDOWS_VERSION_MAJOR")) die("skip not for Windows") +?> --FILE-- <?php umask(022); @@ -11,6 +14,7 @@ $sFile = tempnam(__DIR__, 'test77022'); var_dump(decoct(stat($sFile)['mode'])); foreach([Phar::TAR => 'tar', Phar::ZIP => 'zip'] as $mode => $ext) { + clearstatcache(); $phar = new PharData(__DIR__ . '/test77022.' . $ext, null, null, $mode); $phar->addFile($sFile, 'test-file-phar'); $phar->addFromString("test-from-string", 'test-file-phar'); diff --git a/ext/phar/tests/bug77143.phar b/ext/phar/tests/bug77143.phar Binary files differnew file mode 100644 index 0000000000..eb797b5195 --- /dev/null +++ b/ext/phar/tests/bug77143.phar diff --git a/ext/phar/tests/bug77143.phpt b/ext/phar/tests/bug77143.phpt new file mode 100644 index 0000000000..f9f80fc4f4 --- /dev/null +++ b/ext/phar/tests/bug77143.phpt @@ -0,0 +1,18 @@ +--TEST-- +PHP bug #77143: Heap Buffer Overflow (READ: 4) in phar_parse_pharfile +--INI-- +phar.readonly=0 +--SKIPIF-- +<?php if (!extension_loaded("phar")) die("skip"); ?> +--FILE-- +<?php +chdir(__DIR__); +try { +var_dump(new Phar('bug77143.phar',0,'project.phar')); +echo "OK\n"; +} catch(UnexpectedValueException $e) { + echo $e->getMessage(); +} +?> +--EXPECTF-- +internal corruption of phar "%sbug77143.phar" (truncated manifest header) |