From 13ad4d3e971807f9a58ab5933182907dc2958539 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Wed, 13 Jan 2016 16:32:29 -0800 Subject: Fix bug #71354 - remove UMR when size is 0 --- ext/phar/phar_object.c | 1 + ext/phar/tests/bug71354.phpt | 13 +++++++++++++ ext/phar/tests/bug71354.tar | Bin 0 -> 1536 bytes 3 files changed, 14 insertions(+) create mode 100644 ext/phar/tests/bug71354.phpt create mode 100644 ext/phar/tests/bug71354.tar (limited to 'ext') diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 6d25509cdf..e21a9829e3 100644 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -4884,6 +4884,7 @@ PHP_METHOD(PharFileInfo, getContent) phar_seek_efp(link, 0, SEEK_SET, 0, 0 TSRMLS_CC); Z_TYPE_P(return_value) = IS_STRING; + Z_STRVAL_P(return_value) = NULL; Z_STRLEN_P(return_value) = php_stream_copy_to_mem(fp, &(Z_STRVAL_P(return_value)), link->uncompressed_filesize, 0); if (!Z_STRVAL_P(return_value)) { diff --git a/ext/phar/tests/bug71354.phpt b/ext/phar/tests/bug71354.phpt new file mode 100644 index 0000000000..43230f1520 --- /dev/null +++ b/ext/phar/tests/bug71354.phpt @@ -0,0 +1,13 @@ +--TEST-- +Phar: bug #71354: Heap corruption in tar/zip/phar parser. +--SKIPIF-- + +--FILE-- +getContent()); +?> +DONE +--EXPECT-- +string(0) "" +DONE \ No newline at end of file diff --git a/ext/phar/tests/bug71354.tar b/ext/phar/tests/bug71354.tar new file mode 100644 index 0000000000..b0bd992b9e Binary files /dev/null and b/ext/phar/tests/bug71354.tar differ -- cgit v1.2.1 From 285cd3417fb61597345b829f5f573707bbdcd484 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Wed, 13 Jan 2016 16:43:04 -0800 Subject: Fix bug #71335: Type Confusion in WDDX Packet Deserialization --- ext/wddx/tests/bug71335.phpt | 33 +++++++++++++++++++++++++++++++++ ext/wddx/wddx.c | 3 ++- 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 ext/wddx/tests/bug71335.phpt (limited to 'ext') diff --git a/ext/wddx/tests/bug71335.phpt b/ext/wddx/tests/bug71335.phpt new file mode 100644 index 0000000000..57a7f14f81 --- /dev/null +++ b/ext/wddx/tests/bug71335.phpt @@ -0,0 +1,33 @@ +--TEST-- +Bug #71335 (Type Confusion in WDDX Packet Deserialization) +--SKIPIF-- + +--FILE-- + + +
+ + + + stdClass + + + stdClass + + + +"; + +$d = wddx_deserialize($x); +var_dump($d); +?> +DONE +--EXPECTF-- +object(stdClass)#%d (1) { + ["php_class_name"]=> + string(8) "stdClass" +} +DONE diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c index b9dd1fa78e..7267ee1e94 100644 --- a/ext/wddx/wddx.c +++ b/ext/wddx/wddx.c @@ -978,7 +978,8 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name) if (ent1->varname) { if (!strcmp(ent1->varname, PHP_CLASS_NAME_VAR) && - Z_TYPE_P(ent1->data) == IS_STRING && Z_STRLEN_P(ent1->data) && ent2->type == ST_STRUCT) { + Z_TYPE_P(ent1->data) == IS_STRING && Z_STRLEN_P(ent1->data) && + ent2->type == ST_STRUCT && Z_TYPE_P(ent2->data) == IS_ARRAY) { zend_bool incomplete_class = 0; zend_str_tolower(Z_STRVAL_P(ent1->data), Z_STRLEN_P(ent1->data)); -- cgit v1.2.1 From 4c2424eb24b0178456acc404dbfff528cdc44197 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Thu, 14 Jan 2016 22:58:40 -0800 Subject: Fixed bug #71331 - Uninitialized pointer in phar_make_dirstream() --- ext/phar/dirstream.c | 3 ++- ext/phar/tar.c | 2 +- ext/phar/tests/bug71331.phpt | 15 +++++++++++++++ ext/phar/tests/bug71331.tar | Bin 0 -> 2560 bytes 4 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 ext/phar/tests/bug71331.phpt create mode 100644 ext/phar/tests/bug71331.tar (limited to 'ext') diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c index 05f37e695c..f843501b58 100644 --- a/ext/phar/dirstream.c +++ b/ext/phar/dirstream.c @@ -198,12 +198,13 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC) zend_hash_internal_pointer_reset(manifest); while (FAILURE != zend_hash_has_more_elements(manifest)) { + keylen = 0; if (HASH_KEY_NON_EXISTENT == zend_hash_get_current_key_ex(manifest, &str_key, &keylen, &unused, 0, NULL)) { break; } if (keylen <= (uint)dirlen) { - if (keylen < (uint)dirlen || !strncmp(str_key, dir, dirlen)) { + if (keylen == 0 || keylen < (uint)dirlen || !strncmp(str_key, dir, dirlen)) { if (SUCCESS != zend_hash_move_forward(manifest)) { break; } diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 2eb1a23676..5d121cb030 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -348,7 +348,7 @@ bail: entry.filename_len = entry.uncompressed_filesize; /* Check for overflow - bug 61065 */ - if (entry.filename_len == UINT_MAX) { + if (entry.filename_len == UINT_MAX || entry.filename_len == 0) { if (error) { spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (invalid entry size)", fname); } diff --git a/ext/phar/tests/bug71331.phpt b/ext/phar/tests/bug71331.phpt new file mode 100644 index 0000000000..106fd540fc --- /dev/null +++ b/ext/phar/tests/bug71331.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #71331 (Uninitialized pointer in phar_make_dirstream()) +--SKIPIF-- + +--FILE-- + +DONE +--EXPECTF-- +Fatal error: Uncaught exception 'UnexpectedValueException' with message 'phar error: "%s/bug71331.tar" is a corrupted tar file (invalid entry size)' in %s/bug71331.php:2 +Stack trace: +#0 %s/bug71331.php(2): PharData->__construct('%s') +#1 {main} + thrown in %s/bug71331.php on line 2 \ No newline at end of file diff --git a/ext/phar/tests/bug71331.tar b/ext/phar/tests/bug71331.tar new file mode 100644 index 0000000000..14eec28781 Binary files /dev/null and b/ext/phar/tests/bug71331.tar differ -- cgit v1.2.1 From 1c1b8b69982375700d4b011eb89ea48b66dbd5aa Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sat, 16 Jan 2016 20:43:43 -0800 Subject: Fix bug #71391: NULL Pointer Dereference in phar_tar_setupmetadata() --- ext/phar/tar.c | 3 +++ ext/phar/tests/bug71391.phpt | 18 ++++++++++++++++++ ext/phar/tests/bug71391.tar | Bin 0 -> 3584 bytes 3 files changed, 21 insertions(+) create mode 100644 ext/phar/tests/bug71391.phpt create mode 100644 ext/phar/tests/bug71391.tar (limited to 'ext') diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 34ef0ef892..5f2680590e 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -880,6 +880,9 @@ static int phar_tar_setupmetadata(void *pDest, void *argument TSRMLS_DC) /* {{{ if (entry->filename_len >= sizeof(".phar/.metadata") && !memcmp(entry->filename, ".phar/.metadata", sizeof(".phar/.metadata")-1)) { if (entry->filename_len == sizeof(".phar/.metadata.bin")-1 && !memcmp(entry->filename, ".phar/.metadata.bin", sizeof(".phar/.metadata.bin")-1)) { + if (entry->phar->metadata == NULL) { + return ZEND_HASH_APPLY_REMOVE; + } return phar_tar_setmetadata(entry->phar->metadata, entry, error TSRMLS_CC); } /* search for the file this metadata entry references */ diff --git a/ext/phar/tests/bug71391.phpt b/ext/phar/tests/bug71391.phpt new file mode 100644 index 0000000000..b8d84f5375 --- /dev/null +++ b/ext/phar/tests/bug71391.phpt @@ -0,0 +1,18 @@ +--TEST-- +Phar: bug #71391: NULL Pointer Dereference in phar_tar_setupmetadata() +--SKIPIF-- + +--FILE-- +delMetaData(); +?> +DONE +--CLEAN-- + +--EXPECT-- +DONE \ No newline at end of file diff --git a/ext/phar/tests/bug71391.tar b/ext/phar/tests/bug71391.tar new file mode 100644 index 0000000000..a5b155ac87 Binary files /dev/null and b/ext/phar/tests/bug71391.tar differ -- cgit v1.2.1 From 6297a117d77fa3a0df2e21ca926a92c231819cd5 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sat, 16 Jan 2016 22:10:54 -0800 Subject: Fixed bug #71323 - Output of stream_get_meta_data can be falsified by its input --- ext/standard/streamsfuncs.c | 20 ++-- ext/standard/tests/streams/bug71323.phpt | 31 ++++++ .../streams/stream_get_meta_data_dir_basic.phpt | 16 ++-- .../streams/stream_get_meta_data_file_basic.phpt | 12 +-- .../stream_get_meta_data_file_variation1.phpt | 104 ++++++++++----------- .../stream_get_meta_data_file_variation2.phpt | 46 ++++----- .../stream_get_meta_data_file_variation4.phpt | 20 ++-- .../stream_get_meta_data_file_variation5.phpt | 24 ++--- .../stream_get_meta_data_process_basic.phpt | 12 +-- .../streams/stream_get_meta_data_socket_basic.phpt | 12 +-- .../stream_get_meta_data_socket_variation1.phpt | 44 ++++----- .../stream_get_meta_data_socket_variation2.phpt | 46 ++++----- .../stream_get_meta_data_socket_variation3.phpt | 36 +++---- .../stream_get_meta_data_socket_variation4.phpt | 34 +++---- 14 files changed, 244 insertions(+), 213 deletions(-) create mode 100644 ext/standard/tests/streams/bug71323.phpt (limited to 'ext') diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index 4c2837e28c..d11f1110e8 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -496,6 +496,12 @@ PHP_FUNCTION(stream_get_meta_data) array_init(return_value); + if (!php_stream_populate_meta_data(stream, return_value)) { + add_assoc_bool(return_value, "timed_out", 0); + add_assoc_bool(return_value, "blocked", 1); + add_assoc_bool(return_value, "eof", php_stream_eof(stream)); + } + if (stream->wrapperdata) { MAKE_STD_ZVAL(newval); MAKE_COPY_ZVAL(&stream->wrapperdata, newval); @@ -531,12 +537,6 @@ PHP_FUNCTION(stream_get_meta_data) add_assoc_string(return_value, "uri", stream->orig_path, 1); } - if (!php_stream_populate_meta_data(stream, return_value)) { - add_assoc_bool(return_value, "timed_out", 0); - add_assoc_bool(return_value, "blocked", 1); - add_assoc_bool(return_value, "eof", php_stream_eof(stream)); - } - } /* }}} */ @@ -696,7 +696,7 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC) } else { /* HASH_KEY_IS_STRING */ zend_hash_update(new_hash, key, key_len, (void *)elem, sizeof(zval *), (void **)&dest_elem); } - + if (dest_elem) { zval_add_ref(dest_elem); } @@ -1453,7 +1453,7 @@ PHP_FUNCTION(stream_set_chunk_size) php_error_docref(NULL TSRMLS_CC, E_WARNING, "The chunk size must be a positive integer, given %ld", csize); RETURN_FALSE; } - /* stream.chunk_size is actually a size_t, but php_stream_set_option + /* stream.chunk_size is actually a size_t, but php_stream_set_option * can only use an int to accept the new value and return the old one. * In any case, values larger than INT_MAX for a chunk size make no sense. */ @@ -1461,11 +1461,11 @@ PHP_FUNCTION(stream_set_chunk_size) php_error_docref(NULL TSRMLS_CC, E_WARNING, "The chunk size cannot be larger than %d", INT_MAX); RETURN_FALSE; } - + php_stream_from_zval(stream, &zstream); ret = php_stream_set_option(stream, PHP_STREAM_OPTION_SET_CHUNK_SIZE, (int)csize, NULL); - + RETURN_LONG(ret > 0 ? (long)ret : (long)EOF); } /* }}} */ diff --git a/ext/standard/tests/streams/bug71323.phpt b/ext/standard/tests/streams/bug71323.phpt new file mode 100644 index 0000000000..dfe0bd8afe --- /dev/null +++ b/ext/standard/tests/streams/bug71323.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #71323: Output of stream_get_meta_data can be falsified by its input +--FILE-- + +--EXPECTF-- +array(10) { + ["mediatype"]=> + string(10) "text/plain" + ["z"]=> + string(1) "y" + ["uri"]=> + string(72) "data:text/plain;z=y;uri=eviluri;mediatype=wut?;mediatype2=hello,somedata" + ["mediatype2"]=> + string(5) "hello" + ["base64"]=> + bool(false) + ["wrapper_type"]=> + string(7) "RFC2397" + ["stream_type"]=> + string(7) "RFC2397" + ["mode"]=> + string(1) "r" + ["unread_bytes"]=> + int(0) + ["seekable"]=> + bool(true) +} diff --git a/ext/standard/tests/streams/stream_get_meta_data_dir_basic.phpt b/ext/standard/tests/streams/stream_get_meta_data_dir_basic.phpt index f46c8fd70b..6658d69a4b 100644 --- a/ext/standard/tests/streams/stream_get_meta_data_dir_basic.phpt +++ b/ext/standard/tests/streams/stream_get_meta_data_dir_basic.phpt @@ -13,6 +13,12 @@ var_dump(stream_get_meta_data($dirObject->handle)); ?> --EXPECT-- array(8) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(true) + ["eof"]=> + bool(false) ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -23,14 +29,14 @@ array(8) { int(0) ["seekable"]=> bool(true) +} +array(8) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(8) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -41,10 +47,4 @@ array(8) { int(0) ["seekable"]=> bool(true) - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(true) - ["eof"]=> - bool(false) } diff --git a/ext/standard/tests/streams/stream_get_meta_data_file_basic.phpt b/ext/standard/tests/streams/stream_get_meta_data_file_basic.phpt index 4758c750f9..bad5987990 100644 --- a/ext/standard/tests/streams/stream_get_meta_data_file_basic.phpt +++ b/ext/standard/tests/streams/stream_get_meta_data_file_basic.phpt @@ -12,6 +12,12 @@ fclose($fp); ?> --EXPECTF-- array(9) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(true) + ["eof"]=> + bool(false) ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -24,10 +30,4 @@ array(9) { bool(true) ["uri"]=> string(%i) "%sstream_get_meta_data_file_basic.php" - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(true) - ["eof"]=> - bool(false) } diff --git a/ext/standard/tests/streams/stream_get_meta_data_file_variation1.phpt b/ext/standard/tests/streams/stream_get_meta_data_file_variation1.phpt index 572653e3db..d54eb04410 100644 --- a/ext/standard/tests/streams/stream_get_meta_data_file_variation1.phpt +++ b/ext/standard/tests/streams/stream_get_meta_data_file_variation1.phpt @@ -29,6 +29,12 @@ unlink($filename); ?> --EXPECTF-- array(9) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(true) + ["eof"]=> + bool(false) ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -41,14 +47,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -61,14 +67,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -81,14 +87,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -101,14 +107,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -121,14 +127,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -141,14 +147,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -161,14 +167,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -181,14 +187,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -201,14 +207,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -221,14 +227,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -241,14 +247,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -261,14 +267,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -281,14 +287,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -301,14 +307,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -321,14 +327,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -341,14 +347,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -361,14 +367,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -381,14 +387,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -401,14 +407,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -421,14 +427,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -441,14 +447,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -461,14 +467,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -481,14 +487,14 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -501,10 +507,4 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(true) - ["eof"]=> - bool(false) } diff --git a/ext/standard/tests/streams/stream_get_meta_data_file_variation2.phpt b/ext/standard/tests/streams/stream_get_meta_data_file_variation2.phpt index d186cb7e9b..6b3fde203a 100644 --- a/ext/standard/tests/streams/stream_get_meta_data_file_variation2.phpt +++ b/ext/standard/tests/streams/stream_get_meta_data_file_variation2.phpt @@ -43,6 +43,12 @@ unlink($filename); --EXPECTF-- Write some data to the file: array(9) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(true) + ["eof"]=> + bool(false) ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -55,12 +61,6 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(true) - ["eof"]=> - bool(false) } @@ -68,6 +68,12 @@ Read a line of the file, causing data to be buffered: string(15) "a line of data " array(9) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(true) + ["eof"]=> + bool(false) ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -80,17 +86,17 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" +} + + +Read 20 bytes from the file: +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} - - -Read 20 bytes from the file: -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -103,17 +109,17 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(true) - ["eof"]=> - bool(false) } Read entire file: array(9) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(true) + ["eof"]=> + bool(true) ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -126,10 +132,4 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s.tmp" - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(true) - ["eof"]=> - bool(true) } diff --git a/ext/standard/tests/streams/stream_get_meta_data_file_variation4.phpt b/ext/standard/tests/streams/stream_get_meta_data_file_variation4.phpt index c51d9bd087..46a5ba5b37 100644 --- a/ext/standard/tests/streams/stream_get_meta_data_file_variation4.phpt +++ b/ext/standard/tests/streams/stream_get_meta_data_file_variation4.phpt @@ -28,6 +28,12 @@ unlink($filename); --EXPECTF-- Create a file: array(9) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(true) + ["eof"]=> + bool(false) ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -40,16 +46,16 @@ array(9) { bool(true) ["uri"]=> string(%i) "File://%sstream_get_meta_data_file_variation4.php.tmp" +} + +Change to file's directory and open with a relative path: +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} - -Change to file's directory and open with a relative path: -array(9) { ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -62,10 +68,4 @@ array(9) { bool(true) ["uri"]=> string(%i) "stream_get_meta_data_file_variation4.php.tmp" - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(true) - ["eof"]=> - bool(false) } diff --git a/ext/standard/tests/streams/stream_get_meta_data_file_variation5.phpt b/ext/standard/tests/streams/stream_get_meta_data_file_variation5.phpt index 386b92f421..22fcee4b6f 100644 --- a/ext/standard/tests/streams/stream_get_meta_data_file_variation5.phpt +++ b/ext/standard/tests/streams/stream_get_meta_data_file_variation5.phpt @@ -33,6 +33,12 @@ unlink($filename); --EXPECTF-- Write some data to the file: array(9) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(true) + ["eof"]=> + bool(false) ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -45,17 +51,17 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s" - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(true) - ["eof"]=> - bool(false) } Read entire file: array(9) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(true) + ["eof"]=> + bool(true) ["wrapper_type"]=> string(9) "plainfile" ["stream_type"]=> @@ -68,10 +74,4 @@ array(9) { bool(true) ["uri"]=> string(%i) "%s" - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(true) - ["eof"]=> - bool(true) } diff --git a/ext/standard/tests/streams/stream_get_meta_data_process_basic.phpt b/ext/standard/tests/streams/stream_get_meta_data_process_basic.phpt index 3f4dfbc43a..b7ab37c7c5 100644 --- a/ext/standard/tests/streams/stream_get_meta_data_process_basic.phpt +++ b/ext/standard/tests/streams/stream_get_meta_data_process_basic.phpt @@ -18,6 +18,12 @@ echo "Done"; ?> --EXPECT-- array(7) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(true) + ["eof"]=> + bool(false) ["stream_type"]=> string(5) "STDIO" ["mode"]=> @@ -26,11 +32,5 @@ array(7) { int(0) ["seekable"]=> bool(false) - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(true) - ["eof"]=> - bool(false) } Done diff --git a/ext/standard/tests/streams/stream_get_meta_data_socket_basic.phpt b/ext/standard/tests/streams/stream_get_meta_data_socket_basic.phpt index 86056114b8..c5136ab03b 100644 --- a/ext/standard/tests/streams/stream_get_meta_data_socket_basic.phpt +++ b/ext/standard/tests/streams/stream_get_meta_data_socket_basic.phpt @@ -10,6 +10,12 @@ fclose($tcp_socket); ?> --EXPECTF-- array(7) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(true) + ["eof"]=> + bool(false) ["stream_type"]=> string(%d) "tcp_socke%s" ["mode"]=> @@ -18,10 +24,4 @@ array(7) { int(0) ["seekable"]=> bool(false) - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(true) - ["eof"]=> - bool(false) } diff --git a/ext/standard/tests/streams/stream_get_meta_data_socket_variation1.phpt b/ext/standard/tests/streams/stream_get_meta_data_socket_variation1.phpt index 16b38d9a1b..18d6a4a399 100644 --- a/ext/standard/tests/streams/stream_get_meta_data_socket_variation1.phpt +++ b/ext/standard/tests/streams/stream_get_meta_data_socket_variation1.phpt @@ -39,6 +39,12 @@ var_dump(stream_get_meta_data($client)); --EXPECTF-- Write some data: array(7) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(true) + ["eof"]=> + bool(false) ["stream_type"]=> string(%d) "tcp_socke%s" ["mode"]=> @@ -47,17 +53,17 @@ array(7) { int(0) ["seekable"]=> bool(false) +} + + +Read a line from the client, causing data to be buffered: +array(7) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} - - -Read a line from the client, causing data to be buffered: -array(7) { ["stream_type"]=> string(%d) "tcp_socke%s" ["mode"]=> @@ -66,17 +72,17 @@ array(7) { int(15) ["seekable"]=> bool(false) +} + + +Read 3 bytes of data from the client: +array(7) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} - - -Read 3 bytes of data from the client: -array(7) { ["stream_type"]=> string(%d) "tcp_socke%s" ["mode"]=> @@ -85,17 +91,17 @@ array(7) { int(12) ["seekable"]=> bool(false) - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(true) - ["eof"]=> - bool(false) } Close the server side socket and read the remaining data from the client: array(7) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(true) + ["eof"]=> + bool(true) ["stream_type"]=> string(%d) "tcp_socke%s" ["mode"]=> @@ -104,10 +110,4 @@ array(7) { int(0) ["seekable"]=> bool(false) - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(true) - ["eof"]=> - bool(true) } diff --git a/ext/standard/tests/streams/stream_get_meta_data_socket_variation2.phpt b/ext/standard/tests/streams/stream_get_meta_data_socket_variation2.phpt index d30fec7056..712a661b73 100644 --- a/ext/standard/tests/streams/stream_get_meta_data_socket_variation2.phpt +++ b/ext/standard/tests/streams/stream_get_meta_data_socket_variation2.phpt @@ -37,25 +37,12 @@ fclose($server); ?> --EXPECTF-- array(7) { - ["stream_type"]=> - string(%d) "tcp_socke%s" - ["mode"]=> - string(2) "r+" - ["unread_bytes"]=> - int(0) - ["seekable"]=> - bool(false) ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} - - -Set a timeout on the client and attempt a read: -array(7) { ["stream_type"]=> string(%d) "tcp_socke%s" ["mode"]=> @@ -64,17 +51,17 @@ array(7) { int(0) ["seekable"]=> bool(false) +} + + +Set a timeout on the client and attempt a read: +array(7) { ["timed_out"]=> bool(true) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} - - -Write some data from the server: -array(7) { ["stream_type"]=> string(%d) "tcp_socke%s" ["mode"]=> @@ -83,17 +70,17 @@ array(7) { int(0) ["seekable"]=> bool(false) +} + + +Write some data from the server: +array(7) { ["timed_out"]=> bool(true) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} - - -Read some data from the client: -array(7) { ["stream_type"]=> string(%d) "tcp_socke%s" ["mode"]=> @@ -102,10 +89,23 @@ array(7) { int(0) ["seekable"]=> bool(false) +} + + +Read some data from the client: +array(7) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) + ["stream_type"]=> + string(%d) "tcp_socke%s" + ["mode"]=> + string(2) "r+" + ["unread_bytes"]=> + int(0) + ["seekable"]=> + bool(false) } diff --git a/ext/standard/tests/streams/stream_get_meta_data_socket_variation3.phpt b/ext/standard/tests/streams/stream_get_meta_data_socket_variation3.phpt index 0b079ccf7c..4198973379 100644 --- a/ext/standard/tests/streams/stream_get_meta_data_socket_variation3.phpt +++ b/ext/standard/tests/streams/stream_get_meta_data_socket_variation3.phpt @@ -32,6 +32,12 @@ fclose($server); ?> --EXPECTF-- array(7) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(true) + ["eof"]=> + bool(false) ["stream_type"]=> string(%d) "tcp_socke%s" ["mode"]=> @@ -40,18 +46,18 @@ array(7) { int(0) ["seekable"]=> bool(false) - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(true) - ["eof"]=> - bool(false) } Set blocking to false: bool(true) array(7) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(false) + ["eof"]=> + bool(false) ["stream_type"]=> string(%d) "tcp_socke%s" ["mode"]=> @@ -60,18 +66,18 @@ array(7) { int(0) ["seekable"]=> bool(false) - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(false) - ["eof"]=> - bool(false) } Set blocking to true: bool(true) array(7) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(true) + ["eof"]=> + bool(false) ["stream_type"]=> string(%d) "tcp_socke%s" ["mode"]=> @@ -80,10 +86,4 @@ array(7) { int(0) ["seekable"]=> bool(false) - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(true) - ["eof"]=> - bool(false) } diff --git a/ext/standard/tests/streams/stream_get_meta_data_socket_variation4.phpt b/ext/standard/tests/streams/stream_get_meta_data_socket_variation4.phpt index f9ef747987..50d7ddfb88 100644 --- a/ext/standard/tests/streams/stream_get_meta_data_socket_variation4.phpt +++ b/ext/standard/tests/streams/stream_get_meta_data_socket_variation4.phpt @@ -37,6 +37,12 @@ fclose($client); --EXPECTF-- Write some data: array(7) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(true) + ["eof"]=> + bool(false) ["stream_type"]=> string(%d) "tcp_socke%s" ["mode"]=> @@ -45,17 +51,17 @@ array(7) { int(%i) ["seekable"]=> bool(false) +} + + +Read a line from the client: +array(7) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} - - -Read a line from the client: -array(7) { ["stream_type"]=> string(%d) "tcp_socke%s" ["mode"]=> @@ -64,17 +70,17 @@ array(7) { int(%i) ["seekable"]=> bool(false) - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(true) - ["eof"]=> - bool(false) } Close the server side socket and read the remaining data from the client: array(7) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(true) + ["eof"]=> + bool(true) ["stream_type"]=> string(%d) "tcp_socke%s" ["mode"]=> @@ -83,10 +89,4 @@ array(7) { int(%i) ["seekable"]=> bool(false) - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(true) - ["eof"]=> - bool(true) } -- cgit v1.2.1 From 508d1dae25cb5b8a66f84b3686619bc9ab0a68f8 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Wed, 20 Jan 2016 09:44:28 +0100 Subject: improve fix for bug #71201 --- ext/standard/math.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'ext') diff --git a/ext/standard/math.c b/ext/standard/math.c index b959545c1f..5ffeff7a18 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -145,6 +145,7 @@ PHPAPI double _php_math_round(double value, int places, int mode) { return value; } + places = places < INT_MIN+1 ? INT_MIN+1 : places; precision_places = 14 - php_intlog10abs(value); f1 = php_intpow10(abs(places)); @@ -153,8 +154,10 @@ PHPAPI double _php_math_round(double value, int places, int mode) { the requested places BUT is small enough to make sure a non-zero value is returned, pre-round the result to the precision */ if (precision_places > places && precision_places - places < 15) { - f2 = php_intpow10(abs(precision_places)); - if (precision_places >= 0) { + int64_t use_precision = precision_places < INT_MIN+1 ? INT_MIN+1 : precision_places; + + f2 = php_intpow10(abs((int)use_precision)); + if (use_precision >= 0) { tmp_value = value * f2; } else { tmp_value = value / f2; @@ -162,8 +165,11 @@ PHPAPI double _php_math_round(double value, int places, int mode) { /* preround the result (tmp_value will always be something * 1e14, thus never larger than 1e15 here) */ tmp_value = php_round_helper(tmp_value, mode); + + use_precision = places - precision_places; + use_precision = use_precision < INT_MIN+1 ? INT_MIN+1 : use_precision; /* now correctly move the decimal point */ - f2 = php_intpow10(abs(places - precision_places)); + f2 = php_intpow10(abs((int)use_precision)); /* because places < precision_places */ tmp_value = tmp_value / f2; } else { -- cgit v1.2.1 From 3c8f287d5837f357605184cccd004de017b9f5b4 Mon Sep 17 00:00:00 2001 From: Remi Collet Date: Wed, 20 Jan 2016 13:08:58 +0100 Subject: Fix test when run with openssl < 1.0.2 (reorder so no more SSLv2 message) Fix skip message to work --- ext/standard/tests/streams/stream_socket_enable_crypto.phpt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'ext') diff --git a/ext/standard/tests/streams/stream_socket_enable_crypto.phpt b/ext/standard/tests/streams/stream_socket_enable_crypto.phpt index e316096525..f282c8455b 100644 --- a/ext/standard/tests/streams/stream_socket_enable_crypto.phpt +++ b/ext/standard/tests/streams/stream_socket_enable_crypto.phpt @@ -5,7 +5,7 @@ marcosptf - - #phparty7 - @phpsp - novatec/2015 - sao p --SKIPIF-- Date: Tue, 26 Jan 2016 17:26:52 -0800 Subject: Fix bug #71459 - Integer overflow in iptcembed() --- ext/standard/iptc.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'ext') diff --git a/ext/standard/iptc.c b/ext/standard/iptc.c index 05d778b41b..6f8aa5dc3e 100644 --- a/ext/standard/iptc.c +++ b/ext/standard/iptc.c @@ -195,6 +195,11 @@ PHP_FUNCTION(iptcembed) RETURN_FALSE; } + if ((size_t)iptcdata_len >= SIZE_MAX - sizeof(psheader) - 1025) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "IPTC data too large"); + RETURN_FALSE; + } + if ((fp = VCWD_FOPEN(jpeg_file, "rb")) == 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to open %s", jpeg_file); RETURN_FALSE; @@ -203,7 +208,7 @@ PHP_FUNCTION(iptcembed) if (spool < 2) { fstat(fileno(fp), &sb); - poi = spoolbuf = safe_emalloc(1, iptcdata_len + sizeof(psheader) + sb.st_size + 1024, 1); + poi = spoolbuf = safe_emalloc(1, (size_t)iptcdata_len + sizeof(psheader) + 1024 + 1, sb.st_size); memset(poi, 0, iptcdata_len + sizeof(psheader) + sb.st_size + 1024 + 1); } -- cgit v1.2.1 From 828364e59ca08c2ff3328a648522f9eb05ebbaa3 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Thu, 28 Jan 2016 13:27:26 +0100 Subject: add tests --- .../tests/general_functions/escapeshellarg_bug71039.phpt | 10 ++++++++++ .../tests/general_functions/escapeshellarg_bug71270.phpt | 12 ++++++++++++ .../tests/general_functions/escapeshellcmd_bug71039.phpt | 10 ++++++++++ .../tests/general_functions/escapeshellcmd_bug71270.phpt | 12 ++++++++++++ 4 files changed, 44 insertions(+) create mode 100644 ext/standard/tests/general_functions/escapeshellarg_bug71039.phpt create mode 100644 ext/standard/tests/general_functions/escapeshellarg_bug71270.phpt create mode 100644 ext/standard/tests/general_functions/escapeshellcmd_bug71039.phpt create mode 100644 ext/standard/tests/general_functions/escapeshellcmd_bug71270.phpt (limited to 'ext') diff --git a/ext/standard/tests/general_functions/escapeshellarg_bug71039.phpt b/ext/standard/tests/general_functions/escapeshellarg_bug71039.phpt new file mode 100644 index 0000000000..cbb3f6fcc4 --- /dev/null +++ b/ext/standard/tests/general_functions/escapeshellarg_bug71039.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test escapeshellarg() string with \0 bytes +--FILE-- + +===DONE=== +--EXPECTF-- +Fatal error: escapeshellarg(): Input string contains NULL bytes in %s on line %d diff --git a/ext/standard/tests/general_functions/escapeshellarg_bug71270.phpt b/ext/standard/tests/general_functions/escapeshellarg_bug71270.phpt new file mode 100644 index 0000000000..c57da3691c --- /dev/null +++ b/ext/standard/tests/general_functions/escapeshellarg_bug71270.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test escapeshellarg() allowed argument length +--FILE-- + +===DONE=== +--EXPECTF-- +Fatal error: escapeshellarg(): Argument exceeds the allowed length of %d bytes in %s on line %d diff --git a/ext/standard/tests/general_functions/escapeshellcmd_bug71039.phpt b/ext/standard/tests/general_functions/escapeshellcmd_bug71039.phpt new file mode 100644 index 0000000000..0a4d7eacff --- /dev/null +++ b/ext/standard/tests/general_functions/escapeshellcmd_bug71039.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test escapeshellcmd() string with \0 bytes +--FILE-- + +===DONE=== +--EXPECTF-- +Fatal error: escapeshellcmd(): Input string contains NULL bytes in %s on line %d diff --git a/ext/standard/tests/general_functions/escapeshellcmd_bug71270.phpt b/ext/standard/tests/general_functions/escapeshellcmd_bug71270.phpt new file mode 100644 index 0000000000..4686193d41 --- /dev/null +++ b/ext/standard/tests/general_functions/escapeshellcmd_bug71270.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test escapeshellcmd() allowed argument length +--FILE-- + +===DONE=== +--EXPECTF-- +Fatal error: escapeshellcmd(): Command exceeds the allowed length of %d bytes in %s on line %d -- cgit v1.2.1 From f4d7bbf4ace4ea21c8f95c2d1177bd56a21b86b9 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Thu, 28 Jan 2016 13:45:43 +0100 Subject: backport the escapeshell* functions hardening branch --- ext/standard/basic_functions.c | 1 + ext/standard/exec.c | 76 +++++++++++++++++++++++++++++++++++++++--- ext/standard/exec.h | 1 + 3 files changed, 73 insertions(+), 5 deletions(-) (limited to 'ext') diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index f8cb91ef8e..50b6bc7b68 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -3674,6 +3674,7 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */ #ifdef PHP_CAN_SUPPORT_PROC_OPEN BASIC_MINIT_SUBMODULE(proc_open) #endif + BASIC_MINIT_SUBMODULE(exec) BASIC_MINIT_SUBMODULE(user_streams) BASIC_MINIT_SUBMODULE(imagetypes) diff --git a/ext/standard/exec.c b/ext/standard/exec.c index 66d4537dab..461bef4f72 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -46,10 +46,42 @@ #include #endif -#if HAVE_NICE && HAVE_UNISTD_H +#if HAVE_UNISTD_H #include #endif +#ifdef PHP_WIN32 +# include "win32/php_stdint.h" +#else +# if HAVE_INTTYPES_H +# include +# elif HAVE_STDINT_H +# include +# endif +#endif + +static int cmd_max_len; + +/* {{{ PHP_MINIT_FUNCTION(exec) */ +PHP_MINIT_FUNCTION(exec) +{ +#ifdef _SC_ARG_MAX + cmd_max_len = sysconf(_SC_ARG_MAX); +#elif defined(ARG_MAX) + cmd_max_len = ARG_MAX; +#elif defined(PHP_WIN32) + /* Executed commands will run through cmd.exe. As long as it's the case, + it's just the constant limit.*/ + cmd_max_len = 8192; +#else + /* This is just an arbitrary value for the fallback case. */ + cmd_max_len = 4096; +#endif + + return SUCCESS; +} +/* }}} */ + /* {{{ php_exec * If type==0, only last line of output is returned (exec) * If type==1, all lines will be printed and last lined returned (system) @@ -244,13 +276,20 @@ PHP_FUNCTION(passthru) */ PHPAPI char *php_escape_shell_cmd(char *str) { - register int x, y, l = strlen(str); + register int x, y; + size_t l = strlen(str); + uint64_t estimate = (2 * (uint64_t)l) + 1; char *cmd; char *p = NULL; - size_t estimate = (2 * l) + 1; TSRMLS_FETCH(); + /* max command line length - two single quotes - \0 byte length */ + if (l > cmd_max_len - 2 - 1) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Command exceeds the allowed length of %d bytes", cmd_max_len); + return NULL; + } + cmd = safe_emalloc(2, l, 1); for (x = 0, y = 0; x < l; x++) { @@ -322,6 +361,12 @@ PHPAPI char *php_escape_shell_cmd(char *str) } cmd[y] = '\0'; + if (y - 1 > cmd_max_len) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Escaped command exceeds the allowed length of %d bytes", cmd_max_len); + efree(cmd); + return NULL; + } + if ((estimate - y) > 4096) { /* realloc if the estimate was way overill * Arbitrary cutoff point of 4096 */ @@ -336,12 +381,19 @@ PHPAPI char *php_escape_shell_cmd(char *str) */ PHPAPI char *php_escape_shell_arg(char *str) { - int x, y = 0, l = strlen(str); + int x, y = 0; + size_t l = strlen(str); char *cmd; - size_t estimate = (4 * l) + 3; + uint64_t estimate = (4 * (uint64_t)l) + 3; TSRMLS_FETCH(); + /* max command line length - two single quotes - \0 byte length */ + if (l > cmd_max_len - 2 - 1) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Argument exceeds the allowed length of %d bytes", cmd_max_len); + return NULL; + } + cmd = safe_emalloc(4, l, 3); /* worst case */ #ifdef PHP_WIN32 @@ -396,6 +448,12 @@ PHPAPI char *php_escape_shell_arg(char *str) #endif cmd[y] = '\0'; + if (y - 1 > cmd_max_len) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Escaped argument exceeds the allowed length of %d bytes", cmd_max_len); + efree(cmd); + return NULL; + } + if ((estimate - y) > 4096) { /* realloc if the estimate was way overill * Arbitrary cutoff point of 4096 */ @@ -418,6 +476,10 @@ PHP_FUNCTION(escapeshellcmd) } if (command_len) { + if (command_len != strlen(command)) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Input string contains NULL bytes"); + return; + } cmd = php_escape_shell_cmd(command); RETVAL_STRING(cmd, 0); } else { @@ -439,6 +501,10 @@ PHP_FUNCTION(escapeshellarg) } if (argument) { + if (argument_len != strlen(argument)) { + php_error_docref(NULL TSRMLS_CC, E_ERROR, "Input string contains NULL bytes"); + return; + } cmd = php_escape_shell_arg(argument); RETVAL_STRING(cmd, 0); } diff --git a/ext/standard/exec.h b/ext/standard/exec.h index 399325c759..b106838367 100644 --- a/ext/standard/exec.h +++ b/ext/standard/exec.h @@ -33,6 +33,7 @@ PHP_FUNCTION(proc_close); PHP_FUNCTION(proc_terminate); PHP_FUNCTION(proc_nice); PHP_MINIT_FUNCTION(proc_open); +PHP_MINIT_FUNCTION(exec); PHPAPI char *php_escape_shell_cmd(char *); PHPAPI char *php_escape_shell_arg(char *); -- cgit v1.2.1 From 686a17893a56a500a3a6a4fd721e8ca29412f6dc Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Thu, 28 Jan 2016 13:46:34 +0100 Subject: add missing headers for SIZE_MAX --- ext/standard/iptc.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'ext') diff --git a/ext/standard/iptc.c b/ext/standard/iptc.c index 6f8aa5dc3e..41a924b4b2 100644 --- a/ext/standard/iptc.c +++ b/ext/standard/iptc.c @@ -38,6 +38,15 @@ #include +#ifdef PHP_WIN32 +# include "win32/php_stdint.h" +#else +# if HAVE_INTTYPES_H +# include +# elif HAVE_STDINT_H +# include +# endif +#endif /* some defines for the different JPEG block types */ #define M_SOF0 0xC0 /* Start Of Frame N */ -- cgit v1.2.1 From 07c7df68bd68bbe706371fccc77c814ebb335d9e Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sun, 31 Jan 2016 19:37:56 -0800 Subject: Fixed bug #71488: Stack overflow when decompressing tar archives --- ext/phar/tar.c | 22 ++++++++++++++++------ ext/phar/tests/bug71488.phpt | 16 ++++++++++++++++ ext/phar/tests/bug71488.tar | Bin 0 -> 10240 bytes 3 files changed, 32 insertions(+), 6 deletions(-) create mode 100644 ext/phar/tests/bug71488.phpt create mode 100644 ext/phar/tests/bug71488.tar (limited to 'ext') diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 5f2680590e..3a4bd491f8 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -195,6 +195,13 @@ static int phar_tar_process_metadata(phar_entry_info *entry, php_stream *fp TSRM } /* }}} */ +#if !HAVE_STRNLEN +static size_t strnlen(const char *s, size_t maxlen) { + char *r = (char *)memchr(s, '\0', maxlen); + return r ? r-s : maxlen; +} +#endif + int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, int alias_len, phar_archive_data** pphar, int is_data, php_uint32 compression, char **error TSRMLS_DC) /* {{{ */ { char buf[512], *actual_alias = NULL, *p; @@ -204,6 +211,7 @@ int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, php_uint32 sum1, sum2, size, old; phar_archive_data *myphar, **actual; int last_was_longlink = 0; + int linkname_len; if (error) { *error = NULL; @@ -264,7 +272,7 @@ int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, goto next; } - if (((!old && hdr->prefix[0] == 0) || old) && strlen(hdr->name) == sizeof(".phar/signature.bin")-1 && !strncmp(hdr->name, ".phar/signature.bin", sizeof(".phar/signature.bin")-1)) { + if (((!old && hdr->prefix[0] == 0) || old) && strnlen(hdr->name, 100) == sizeof(".phar/signature.bin")-1 && !strncmp(hdr->name, ".phar/signature.bin", sizeof(".phar/signature.bin")-1)) { off_t curloc; if (size > 511) { @@ -474,20 +482,22 @@ bail: } entry.link = NULL; - + /* link field is null-terminated unless it has 100 non-null chars. + * Thus we can not use strlen. */ + linkname_len = strnlen(hdr->linkname, 100); if (entry.tar_type == TAR_LINK) { - if (!zend_hash_exists(&myphar->manifest, hdr->linkname, strlen(hdr->linkname))) { + if (!zend_hash_exists(&myphar->manifest, hdr->linkname, linkname_len)) { if (error) { - spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file - hard link to non-existent file \"%s\"", fname, hdr->linkname); + spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file - hard link to non-existent file \"%.*s\"", fname, linkname_len, hdr->linkname); } pefree(entry.filename, entry.is_persistent); php_stream_close(fp); phar_destroy_phar_data(myphar TSRMLS_CC); return FAILURE; } - entry.link = estrdup(hdr->linkname); + entry.link = estrndup(hdr->linkname, linkname_len); } else if (entry.tar_type == TAR_SYMLINK) { - entry.link = estrdup(hdr->linkname); + entry.link = estrndup(hdr->linkname, linkname_len); } phar_set_inode(&entry TSRMLS_CC); zend_hash_add(&myphar->manifest, entry.filename, entry.filename_len, (void*)&entry, sizeof(phar_entry_info), (void **) &newentry); diff --git a/ext/phar/tests/bug71488.phpt b/ext/phar/tests/bug71488.phpt new file mode 100644 index 0000000000..05fdd8f481 --- /dev/null +++ b/ext/phar/tests/bug71488.phpt @@ -0,0 +1,16 @@ +--TEST-- +Phar: bug #71488: Stack overflow when decompressing tar archives +--SKIPIF-- + +--FILE-- +decompress("test"); +?> +DONE +--CLEAN-- + +--EXPECT-- +DONE \ No newline at end of file diff --git a/ext/phar/tests/bug71488.tar b/ext/phar/tests/bug71488.tar new file mode 100644 index 0000000000..6e14195025 Binary files /dev/null and b/ext/phar/tests/bug71488.tar differ -- cgit v1.2.1 From 2a7d8c0a06de8123034b136b0c717576b6e36fae Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 1 Feb 2016 18:58:02 -0800 Subject: fix tests --- ext/standard/tests/file/stream_rfc2397_002.phpt | 56 +++++++++++----------- .../tests/network/socket_get_status_basic.phpt | 12 ++--- ext/zip/tests/stream_meta_data.phpt | 16 +++---- ext/zlib/tests/zlib_wrapper_meta_data_basic.phpt | 20 ++++---- 4 files changed, 52 insertions(+), 52 deletions(-) (limited to 'ext') diff --git a/ext/standard/tests/file/stream_rfc2397_002.phpt b/ext/standard/tests/file/stream_rfc2397_002.phpt index 980863bb5c..1dce5adf6c 100644 --- a/ext/standard/tests/file/stream_rfc2397_002.phpt +++ b/ext/standard/tests/file/stream_rfc2397_002.phpt @@ -34,6 +34,8 @@ foreach($streams as $stream) --EXPECTF-- array(7) { + ["base64"]=> + bool(false) ["wrapper_type"]=> string(7) "RFC2397" ["stream_type"]=> @@ -46,8 +48,6 @@ array(7) { bool(true) ["uri"]=> string(8) "data://," - ["base64"]=> - bool(false) } NULL @@ -55,6 +55,8 @@ Warning: fopen(data://): failed to open stream: rfc2397: no comma in URL in %sst NULL NULL array(7) { + ["base64"]=> + bool(true) ["wrapper_type"]=> string(7) "RFC2397" ["stream_type"]=> @@ -67,8 +69,6 @@ array(7) { bool(true) ["uri"]=> string(15) "data://;base64," - ["base64"]=> - bool(true) } NULL @@ -84,6 +84,10 @@ Warning: fopen(data://foo=bar,): failed to open stream: rfc2397: illegal media t NULL NULL array(8) { + ["mediatype"]=> + string(10) "text/plain" + ["base64"]=> + bool(false) ["wrapper_type"]=> string(7) "RFC2397" ["stream_type"]=> @@ -96,10 +100,6 @@ array(8) { bool(true) ["uri"]=> string(18) "data://text/plain," - ["mediatype"]=> - string(10) "text/plain" - ["base64"]=> - bool(false) } NULL @@ -107,6 +107,12 @@ Warning: fopen(data://text/plain;foo,): failed to open stream: rfc2397: illegal NULL NULL array(9) { + ["mediatype"]=> + string(10) "text/plain" + ["foo"]=> + string(3) "bar" + ["base64"]=> + bool(false) ["wrapper_type"]=> string(7) "RFC2397" ["stream_type"]=> @@ -119,12 +125,6 @@ array(9) { bool(true) ["uri"]=> string(26) "data://text/plain;foo=bar," - ["mediatype"]=> - string(10) "text/plain" - ["foo"]=> - string(3) "bar" - ["base64"]=> - bool(false) } string(3) "bar" @@ -132,6 +132,12 @@ Warning: fopen(data://text/plain;foo=bar;bla,): failed to open stream: rfc2397: NULL NULL array(9) { + ["mediatype"]=> + string(10) "text/plain" + ["foo"]=> + string(3) "bar" + ["base64"]=> + bool(true) ["wrapper_type"]=> string(7) "RFC2397" ["stream_type"]=> @@ -144,12 +150,6 @@ array(9) { bool(true) ["uri"]=> string(33) "data://text/plain;foo=bar;base64," - ["mediatype"]=> - string(10) "text/plain" - ["foo"]=> - string(3) "bar" - ["base64"]=> - bool(true) } string(3) "bar" @@ -157,6 +157,14 @@ Warning: fopen(data://text/plain;foo=bar;bar=baz): failed to open stream: rfc239 NULL NULL array(10) { + ["mediatype"]=> + string(10) "text/plain" + ["foo"]=> + string(3) "bar" + ["bar"]=> + string(3) "baz" + ["base64"]=> + bool(false) ["wrapper_type"]=> string(7) "RFC2397" ["stream_type"]=> @@ -169,14 +177,6 @@ array(10) { bool(true) ["uri"]=> string(34) "data://text/plain;foo=bar;bar=baz," - ["mediatype"]=> - string(10) "text/plain" - ["foo"]=> - string(3) "bar" - ["bar"]=> - string(3) "baz" - ["base64"]=> - bool(false) } string(3) "bar" ===DONE=== diff --git a/ext/standard/tests/network/socket_get_status_basic.phpt b/ext/standard/tests/network/socket_get_status_basic.phpt index 46215f9838..32a8d9ce6f 100644 --- a/ext/standard/tests/network/socket_get_status_basic.phpt +++ b/ext/standard/tests/network/socket_get_status_basic.phpt @@ -18,6 +18,12 @@ fclose($server); ?> --EXPECTF-- array(7) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(true) + ["eof"]=> + bool(false) ["stream_type"]=> string(%d) "tcp_socket%S" ["mode"]=> @@ -26,10 +32,4 @@ array(7) { int(0) ["seekable"]=> bool(false) - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(true) - ["eof"]=> - bool(false) } diff --git a/ext/zip/tests/stream_meta_data.phpt b/ext/zip/tests/stream_meta_data.phpt index bd080980ed..63f720ad85 100644 --- a/ext/zip/tests/stream_meta_data.phpt +++ b/ext/zip/tests/stream_meta_data.phpt @@ -35,6 +35,12 @@ fclose($fp); ?> --EXPECTF-- array(8) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(true) + ["eof"]=> + bool(false) ["stream_type"]=> string(3) "zip" ["mode"]=> @@ -45,14 +51,14 @@ array(8) { bool(false) ["uri"]=> string(3) "foo" +} +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} -array(9) { ["wrapper_type"]=> string(11) "zip wrapper" ["stream_type"]=> @@ -65,10 +71,4 @@ array(9) { bool(false) ["uri"]=> string(%d) "zip://%stest_with_comment.zip#foo" - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(true) - ["eof"]=> - bool(false) } diff --git a/ext/zlib/tests/zlib_wrapper_meta_data_basic.phpt b/ext/zlib/tests/zlib_wrapper_meta_data_basic.phpt index 2f76b46d96..a9d208eeaa 100644 --- a/ext/zlib/tests/zlib_wrapper_meta_data_basic.phpt +++ b/ext/zlib/tests/zlib_wrapper_meta_data_basic.phpt @@ -25,6 +25,12 @@ gzclose($h); --EXPECTF-- no wrapper array(7) { + ["timed_out"]=> + bool(false) + ["blocked"]=> + bool(true) + ["eof"]=> + bool(false) ["stream_type"]=> string(4) "ZLIB" ["mode"]=> @@ -33,16 +39,16 @@ array(7) { int(0) ["seekable"]=> bool(true) +} + +with wrapper +array(9) { ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) -} - -with wrapper -array(9) { ["wrapper_type"]=> string(4) "ZLIB" ["stream_type"]=> @@ -55,11 +61,5 @@ array(9) { bool(true) ["uri"]=> string(%d) "compress.zlib://%s/004.txt.gz" - ["timed_out"]=> - bool(false) - ["blocked"]=> - bool(true) - ["eof"]=> - bool(false) } ===DONE=== \ No newline at end of file -- cgit v1.2.1