From 282bfb109ecd07cd76761c098304a45bd214e439 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sat, 15 Feb 2020 20:52:19 -0800 Subject: [PATCH 1/4] Fix bug #79221 - Null Pointer Dereference in PHP Session Upload Progress --- ext/session/session.c | 10 +++++--- ext/session/tests/bug79221.phpt | 45 +++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 ext/session/tests/bug79221.phpt diff --git a/ext/session/session.c b/ext/session/session.c index 7c7e4841e4f..092dea81ce2 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -3320,10 +3320,12 @@ static int php_session_rfc1867_callback(unsigned int event, void *event_data, vo if (PS(rfc1867_cleanup)) { php_session_rfc1867_cleanup(progress); } else { - SEPARATE_ARRAY(&progress->data); - add_assoc_bool_ex(&progress->data, "done", sizeof("done") - 1, 1); - Z_LVAL_P(progress->post_bytes_processed) = data->post_bytes_processed; - php_session_rfc1867_update(progress, 1); + if (!Z_ISUNDEF(progress->data)) { + SEPARATE_ARRAY(&progress->data); + add_assoc_bool_ex(&progress->data, "done", sizeof("done") - 1, 1); + Z_LVAL_P(progress->post_bytes_processed) = data->post_bytes_processed; + php_session_rfc1867_update(progress, 1); + } } php_rshutdown_session_globals(); } diff --git a/ext/session/tests/bug79221.phpt b/ext/session/tests/bug79221.phpt new file mode 100644 index 00000000000..b0972c46970 --- /dev/null +++ b/ext/session/tests/bug79221.phpt @@ -0,0 +1,45 @@ +--TEST-- +Null Pointer Dereference in PHP Session Upload Progress +--INI-- +error_reporting=0 +file_uploads=1 +upload_max_filesize=1024 +session.save_path= +session.name=PHPSESSID +session.serialize_handler=php +session.use_strict_mode=0 +session.use_cookies=1 +session.use_only_cookies=0 +session.upload_progress.enabled=1 +session.upload_progress.cleanup=0 +session.upload_progress.prefix=upload_progress_ +session.upload_progress.name=PHP_SESSION_UPLOAD_PROGRESS +session.upload_progress.freq=1% +session.upload_progress.min_freq=0.000000001 +--COOKIE-- +PHPSESSID=session-upload +--POST_RAW-- +Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 +-----------------------------20896060251896012921717172737 +Content-Disposition: form-data; name="PHPSESSID" + +session-upload +-----------------------------20896060251896012921717172737 +Content-Disposition: form-data; name="PHP_SESSION_UPLOAD_PROGRESS" + +ryat +-----------------------------20896060251896012921717172737 +Content-Disposition: form-data; file="file"; ryat="filename" + +1 +-----------------------------20896060251896012921717172737-- +--FILE-- + Date: Sat, 15 Feb 2020 22:17:14 -0800 Subject: [PATCH 2/4] Fix bug #79082 - Files added to tar with Phar::buildFromIterator have all-access permissions --- ext/phar/phar_object.c | 11 +++++ ext/phar/tests/bug79082.phpt | 52 ++++++++++++++++++++ ext/phar/tests/test79082/test79082-testfile | 1 + ext/phar/tests/test79082/test79082-testfile2 | 1 + 4 files changed, 65 insertions(+) create mode 100644 ext/phar/tests/bug79082.phpt create mode 100644 ext/phar/tests/test79082/test79082-testfile create mode 100644 ext/phar/tests/test79082/test79082-testfile2 diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 6cf097e36fe..89b553c2b91 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -1419,6 +1419,7 @@ static int phar_build(zend_object_iterator *iter, void *puser) /* {{{ */ char *str_key; zend_class_entry *ce = p_obj->c; phar_archive_object *phar_obj = p_obj->p; + php_stream_statbuf ssb; value = iter->funcs->get_current_data(iter); @@ -1686,6 +1687,16 @@ after_open_fp: php_stream_copy_to_stream_ex(fp, p_obj->fp, PHP_STREAM_COPY_ALL, &contents_len); data->internal_file->uncompressed_filesize = data->internal_file->compressed_filesize = php_stream_tell(p_obj->fp) - data->internal_file->offset; + if (php_stream_stat(fp, &ssb) != -1) { + data->internal_file->flags = ssb.sb.st_mode & PHAR_ENT_PERM_MASK ; + } else { +#ifndef _WIN32 + mode_t mask; + mask = umask(0); + umask(mask); + data->internal_file->flags &= ~mask; +#endif + } } if (close_fp) { diff --git a/ext/phar/tests/bug79082.phpt b/ext/phar/tests/bug79082.phpt new file mode 100644 index 00000000000..ca453d1b57b --- /dev/null +++ b/ext/phar/tests/bug79082.phpt @@ -0,0 +1,52 @@ +--TEST-- +Phar: Bug #79082: Files added to tar with Phar::buildFromIterator have all-access permissions +--SKIPIF-- + +--FILE-- + 'tar', Phar::ZIP => 'zip'] as $mode => $ext) { + clearstatcache(); + $phar = new PharData(__DIR__ . '/test79082.' . $ext, null, null, $mode); + $phar->buildFromIterator(new \RecursiveDirectoryIterator(__DIR__ . '/test79082', \FilesystemIterator::SKIP_DOTS), __DIR__ . '/test79082'); + $phar->extractTo(__DIR__); + var_dump(decoct(stat(__DIR__ . '/test79082-testfile')['mode'])); + var_dump(decoct(stat(__DIR__ . '/test79082-testfile2')['mode'])); + unlink(__DIR__ . '/test79082-testfile'); + unlink(__DIR__ . '/test79082-testfile2'); +} +foreach([Phar::TAR => 'tar', Phar::ZIP => 'zip'] as $mode => $ext) { + clearstatcache(); + $phar = new PharData(__DIR__ . '/test79082-d.' . $ext, null, null, $mode); + $phar->buildFromDirectory(__DIR__ . '/test79082'); + $phar->extractTo(__DIR__); + var_dump(decoct(stat(__DIR__ . '/test79082-testfile')['mode'])); + var_dump(decoct(stat(__DIR__ . '/test79082-testfile2')['mode'])); + unlink(__DIR__ . '/test79082-testfile'); + unlink(__DIR__ . '/test79082-testfile2'); +} +?> +--CLEAN-- + +--EXPECT-- +string(2) "22" +string(6) "100644" +string(6) "100400" +string(6) "100644" +string(6) "100400" +string(6) "100644" +string(6) "100400" +string(6) "100644" +string(6) "100400" diff --git a/ext/phar/tests/test79082/test79082-testfile b/ext/phar/tests/test79082/test79082-testfile new file mode 100644 index 00000000000..9daeafb9864 --- /dev/null +++ b/ext/phar/tests/test79082/test79082-testfile @@ -0,0 +1 @@ +test diff --git a/ext/phar/tests/test79082/test79082-testfile2 b/ext/phar/tests/test79082/test79082-testfile2 new file mode 100644 index 00000000000..9daeafb9864 --- /dev/null +++ b/ext/phar/tests/test79082/test79082-testfile2 @@ -0,0 +1 @@ +test From b01b1f65e77325e16f4cca4d0cb1dff48891680c Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 26 Jan 2020 16:03:35 +0100 Subject: [PATCH 3/4] Fix # 79171: heap-buffer-overflow in phar_extract_file We must not access memory outside of the allocated buffer. --- ext/phar/phar_object.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 89b553c2b91..eaa74ece94a 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -4184,7 +4184,7 @@ static int phar_extract_file(zend_bool overwrite, phar_entry_info *entry, char * if ('\\' == filename[cnt]) { filename[cnt] = '/'; } - } while (cnt++ <= filename_len); + } while (cnt++ < filename_len); } #endif From 54ecf57fe290f69a2112d4c2ea3a1e99208e2797 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Mon, 17 Feb 2020 12:48:55 +0300 Subject: [PATCH 4/4] Disable instantiation of zero size FFI\CData objects --- ext/ffi/ffi.c | 6 ++++++ ext/ffi/tests/023.phpt | 8 ++++++-- ext/ffi/tests/027.phpt | 2 +- ext/ffi/tests/045.phpt | 2 +- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/ext/ffi/ffi.c b/ext/ffi/ffi.c index f43ba2adc8d..d99448dd69f 100644 --- a/ext/ffi/ffi.c +++ b/ext/ffi/ffi.c @@ -3685,6 +3685,12 @@ ZEND_METHOD(FFI, new) /* {{{ */ } } + if (type->size == 0) { + zend_throw_error(zend_ffi_exception_ce, "Cannot instantiate FFI\\CData of zero size"); + zend_ffi_type_dtor(type_ptr); + return; + } + ptr = pemalloc(type->size, flags & ZEND_FFI_FLAG_PERSISTENT); memset(ptr, 0, type->size); diff --git a/ext/ffi/tests/023.phpt b/ext/ffi/tests/023.phpt index 37036203906..920a3bee3ec 100644 --- a/ext/ffi/tests/023.phpt +++ b/ext/ffi/tests/023.phpt @@ -6,13 +6,17 @@ FFI 023: GCC struct extensions ffi.enable=1 --FILE-- getMessage() . "\n"; + } var_dump(FFI::sizeof(FFI::new("struct {int a}"))); var_dump(FFI::sizeof(FFI::new("struct {int a; int b}"))); ?> ok --EXPECT-- -int(0) +FFI\Exception: Cannot instantiate FFI\CData of zero size int(4) int(8) ok diff --git a/ext/ffi/tests/027.phpt b/ext/ffi/tests/027.phpt index 14c51f77e42..6e3e76204b6 100644 --- a/ext/ffi/tests/027.phpt +++ b/ext/ffi/tests/027.phpt @@ -81,7 +81,7 @@ FFI\ParserException: '[*]' not allowed in other than function prototype scope at FFI\ParserException: '[*]' not allowed in other than function prototype scope at line 1 FFI\ParserException: '[*]' not allowed in other than function prototype scope at line 1 ok -int(0) +FFI\Exception: Cannot instantiate FFI\CData of zero size FFI\ParserException: '[]' not allowed at line 1 FFI\ParserException: '[]' not allowed at line 1 ok diff --git a/ext/ffi/tests/045.phpt b/ext/ffi/tests/045.phpt index 7118df9eb7b..b73c38aefb5 100644 --- a/ext/ffi/tests/045.phpt +++ b/ext/ffi/tests/045.phpt @@ -26,4 +26,4 @@ bool(false) Warning: FFI::isNull() expects parameter 1 to be FFI\CData, null given in %s045.php on line %d NULL -FFI\Exception: FFI\Cdata is not a pointer +FFI\Exception: Cannot instantiate FFI\CData of zero size