From f0120ff8787ce5efc509a8365fd815d1144c366e Mon Sep 17 00:00:00 2001 From: Julien Pauli Date: Tue, 29 Mar 2016 18:11:03 +0200 Subject: [PATCH 1/9] 5.5.35 now --- NEWS | 22 +++++++++++++++++++++- configure.in | 2 +- main/php_version.h | 6 +++--- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 6d3caf60def..8859d6c57cb 100644 --- a/NEWS +++ b/NEWS @@ -2,9 +2,29 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ** PHP 5.5 is in security-only mode , please do not commit to this branch ** -??? 2016, PHP 5.5.34 +??? 2016, PHP 5.5.35 +31 Mar 2016, PHP 5.5.34 +- Fileinfo: + . Fixed bug #71527 (Buffer over-write in finfo_open with malformed magic + file). (Anatol) + +- Mbstring: + . Fixed bug #71906 (AddressSanitizer: negative-size-param (-1) in + mbfl_strcut). (Stas) + +- OBBC + . Fixed bug #71860 (Invalid memory write in phar on filename with \0 in + name). (Stas) + +- SNMP: + . Fixed bug #71704 (php_snmp_error() Format String Vulnerability). + (andrew at jmpesp dot org) + +- Standard + . Fixed bug #71798 (Integer Overflow in php_raw_url_encode). + (taoguangchen at icloud dot com, Stas) 03 Mar 2016, PHP 5.5.33 diff --git a/configure.in b/configure.in index 21a52065c55..c46011a30db 100644 --- a/configure.in +++ b/configure.in @@ -119,7 +119,7 @@ int zend_sprintf(char *buffer, const char *format, ...); PHP_MAJOR_VERSION=5 PHP_MINOR_VERSION=5 -PHP_RELEASE_VERSION=34 +PHP_RELEASE_VERSION=35 PHP_EXTRA_VERSION="-dev" PHP_VERSION="$PHP_MAJOR_VERSION.$PHP_MINOR_VERSION.$PHP_RELEASE_VERSION$PHP_EXTRA_VERSION" PHP_VERSION_ID=`expr [$]PHP_MAJOR_VERSION \* 10000 + [$]PHP_MINOR_VERSION \* 100 + [$]PHP_RELEASE_VERSION` diff --git a/main/php_version.h b/main/php_version.h index 25446e3d65e..f87cc38eda9 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -2,7 +2,7 @@ /* edit configure.in to change version number */ #define PHP_MAJOR_VERSION 5 #define PHP_MINOR_VERSION 5 -#define PHP_RELEASE_VERSION 34 +#define PHP_RELEASE_VERSION 35 #define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "5.5.34-dev" -#define PHP_VERSION_ID 50534 +#define PHP_VERSION "5.5.35-dev" +#define PHP_VERSION_ID 50535 From 3bfe1c55ae72f6f2c1cccc641e46f26114376ecd Mon Sep 17 00:00:00 2001 From: Matteo Beccati Date: Wed, 30 Mar 2016 10:00:28 +0200 Subject: [PATCH 2/9] Removed shmop test leaking an shm segment --- ext/shmop/shmop.c | 1 + ext/shmop/tests/003.phpt | 33 --------------------------------- 2 files changed, 1 insertion(+), 33 deletions(-) delete mode 100644 ext/shmop/tests/003.phpt diff --git a/ext/shmop/shmop.c b/ext/shmop/shmop.c index 4fe65ae37d0..d647790aa06 100644 --- a/ext/shmop/shmop.c +++ b/ext/shmop/shmop.c @@ -203,6 +203,7 @@ PHP_FUNCTION(shmop_open) } if (shmctl(shmop->shmid, IPC_STAT, &shm)) { + /* please do not add coverage here: the segment would be leaked and impossible to delete via php */ php_error_docref(NULL, E_WARNING, "unable to get shared memory segment information '%s'", strerror(errno)); goto err; } diff --git a/ext/shmop/tests/003.phpt b/ext/shmop/tests/003.phpt deleted file mode 100644 index 1c154f08ca0..00000000000 --- a/ext/shmop/tests/003.phpt +++ /dev/null @@ -1,33 +0,0 @@ ---TEST-- -shmop extension error messages (non-root) ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -## shmop_open function tests ## - -Warning: shmop_open(): unable to get shared memory segment information 'Permission denied' in %s on line %d -bool(false) From f95679885ff9a7258f0a91b9d83d73a7ee7e6f91 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Wed, 30 Mar 2016 18:31:10 +0200 Subject: [PATCH 3/9] Fix __invoke comparison in closure_get_method It compared against the wrong variable. Fixed this by getting rid of lc_name entirely and use equals_literal_ci instead. --- Zend/tests/closure_invoke_case_insensitive.phpt | 16 ++++++++++++++++ Zend/zend_closures.c | 8 ++------ 2 files changed, 18 insertions(+), 6 deletions(-) create mode 100644 Zend/tests/closure_invoke_case_insensitive.phpt diff --git a/Zend/tests/closure_invoke_case_insensitive.phpt b/Zend/tests/closure_invoke_case_insensitive.phpt new file mode 100644 index 00000000000..d41d58a747c --- /dev/null +++ b/Zend/tests/closure_invoke_case_insensitive.phpt @@ -0,0 +1,16 @@ +--TEST-- +Closure::__invoke() is case insensitive +--FILE-- +__INVOKE($n); +var_dump($n); + +?> +--EXPECT-- +int(2) diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index 9b4fb1180e8..def114c4ec5 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -297,14 +297,10 @@ ZEND_API zval* zend_get_closure_this_ptr(zval *obj) /* {{{ */ static zend_function *zend_closure_get_method(zend_object **object, zend_string *method, const zval *key) /* {{{ */ { - zend_string *lc_name; - - lc_name = zend_string_tolower(method); - if (zend_string_equals_literal(method, ZEND_INVOKE_FUNC_NAME)) { - zend_string_release(lc_name); + if (zend_string_equals_literal_ci(method, ZEND_INVOKE_FUNC_NAME)) { return zend_get_closure_invoke_method(*object); } - zend_string_release(lc_name); + return std_object_handlers.get_method(object, method, key); } /* }}} */ From abd59c0e400173d36abe49930bd56b8d37b0dfc1 Mon Sep 17 00:00:00 2001 From: Ferenc Kovacs Date: Wed, 30 Mar 2016 22:28:28 +0200 Subject: [PATCH 4/9] update NEWS --- NEWS | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/NEWS b/NEWS index 1f2a906f81c..20cb8767623 100644 --- a/NEWS +++ b/NEWS @@ -48,9 +48,19 @@ PHP NEWS - Date: . Fixed bug #71635 (DatePeriod::getEndDate segfault). (Thomas Punt) +- Fileinfo: + . Fixed bug #71527 (Buffer over-write in finfo_open with malformed magic + file). (Anatol) + +- Mbstring: + . Fixed bug #71906 (AddressSanitizer: negative-size-param (-1) in + mbfl_strcut). (Stas) + - ODBC: . Fixed bug #47803, #69526 (Executing prepared statements is succesfull only for the first two statements). (einavitamar at gmail dot com, Anatol) + . Fixed bug #71860 (Invalid memory write in phar on filename with \0 in + name). (Stas) - PDO_DBlib: . Bug #54648 (PDO::MSSQL forces format of datetime fields). @@ -62,6 +72,14 @@ PHP NEWS . Fixed bug #71504 (Parsing of tar file with duplicate filenames causes memory leak). (Jos Elstgeest) +- SNMP: + . Fixed bug #71704 (php_snmp_error() Format String Vulnerability). + (andrew at jmpesp dot org) + +- Standard + . Fixed bug #71798 (Integer Overflow in php_raw_url_encode). + (taoguangchen at icloud dot com, Stas) + 03 Mar 2016, PHP 5.6.19 - CLI server: From b1e854f7762b2e0648ddc240835cb446ee4d20a7 Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Tue, 12 Jan 2016 16:31:58 +0100 Subject: [PATCH 5/9] Fix bug #71334 Always duplicate the array before doing a sort with user-defined comparison function, to avoid access to the intermediate inconsistent state. I've also dropped the "array modification" warning, as protection against modifications is no longer relevant if we're always working on a copy anyway. This also required some changes to how SplArray forwards calls to sorting functions. --- NEWS | 1 + ext/spl/spl_array.c | 45 ++++++++++++------- ext/standard/array.c | 35 ++++++--------- ext/standard/tests/array/bug71334.phpt | 38 ++++++++++++++++ .../tests/array/unexpected_array_mod_bug.phpt | 21 ++++++--- .../unexpected_array_mod_bug_variation1.phpt | 33 ++++++++++++++ 6 files changed, 131 insertions(+), 42 deletions(-) create mode 100644 ext/standard/tests/array/bug71334.phpt create mode 100644 ext/standard/tests/array/unexpected_array_mod_bug_variation1.phpt diff --git a/NEWS b/NEWS index abf70d04c1f..b8e4eefe090 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,7 @@ PHP NEWS . Fixed bug #62059 (ArrayObject and isset are not friends). (Nikita) . Fixed bug #71871 (Interfaces allow final and abstract functions). (Nikita) . Fixed bug #71922 (Crash on assert(new class{})). (Nikita) + . Fixed bug #71334 (Cannot access array keys while uksort()). (Nikita) - Curl: . Fixed bug #71831 (CURLOPT_NOPROXY applied as long instead of string). diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index d5cb32606ea..60cbac57269 100644 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -82,18 +82,18 @@ static inline spl_array_object *spl_array_from_obj(zend_object *obj) /* {{{ */ { #define Z_SPLARRAY_P(zv) spl_array_from_obj(Z_OBJ_P((zv))) -static inline HashTable *spl_array_get_hash_table(spl_array_object* intern) { /* {{{ */ +static inline HashTable **spl_array_get_hash_table_ptr(spl_array_object* intern) { /* {{{ */ //??? TODO: Delay duplication for arrays; only duplicate for write operations if (intern->ar_flags & SPL_ARRAY_IS_SELF) { if (!intern->std.properties) { rebuild_object_properties(&intern->std); } - return intern->std.properties; + return &intern->std.properties; } else if (intern->ar_flags & SPL_ARRAY_USE_OTHER) { spl_array_object *other = Z_SPLARRAY_P(&intern->array); - return spl_array_get_hash_table(other); + return spl_array_get_hash_table_ptr(other); } else if (Z_TYPE(intern->array) == IS_ARRAY) { - return Z_ARRVAL(intern->array); + return &Z_ARRVAL(intern->array); } else { zend_object *obj = Z_OBJ(intern->array); if (!obj->properties) { @@ -104,9 +104,22 @@ static inline HashTable *spl_array_get_hash_table(spl_array_object* intern) { /* } obj->properties = zend_array_dup(obj->properties); } - return obj->properties; + return &obj->properties; } -} /* }}} */ +} +/* }}} */ + +static inline HashTable *spl_array_get_hash_table(spl_array_object* intern) { /* {{{ */ + return *spl_array_get_hash_table_ptr(intern); +} +/* }}} */ + +static inline void spl_array_replace_hash_table(spl_array_object* intern, HashTable *ht) { /* {{{ */ + HashTable **ht_ptr = spl_array_get_hash_table_ptr(intern); + zend_array_destroy(*ht_ptr); + *ht_ptr = ht; +} +/* }}} */ static inline zend_bool spl_array_is_object(spl_array_object *intern) /* {{{ */ { @@ -1432,16 +1445,12 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fnam spl_array_object *intern = Z_SPLARRAY_P(getThis()); HashTable *aht = spl_array_get_hash_table(intern); zval function_name, params[2], *arg = NULL; - uint32_t old_refcount; ZVAL_STRINGL(&function_name, fname, fname_len); - /* A tricky way to pass "aht" by reference, reset refcount */ - //??? It may be not safe, if user comparison handler accesses "aht" - old_refcount = GC_REFCOUNT(aht); - GC_REFCOUNT(aht) = 1; ZVAL_NEW_EMPTY_REF(¶ms[0]); ZVAL_ARR(Z_REFVAL(params[0]), aht); + GC_REFCOUNT(aht)++; if (!use_arg) { intern->nApplyCount++; @@ -1470,10 +1479,16 @@ static void spl_array_method(INTERNAL_FUNCTION_PARAMETERS, char *fname, int fnam } exit: - /* A tricky way to pass "aht" by reference, copy back and cleanup */ - GC_REFCOUNT(aht) = old_refcount; - efree(Z_REF(params[0])); - zend_string_free(Z_STR(function_name)); + { + HashTable *new_ht = Z_ARRVAL_P(Z_REFVAL(params[0])); + if (aht != new_ht) { + spl_array_replace_hash_table(intern, new_ht); + } else { + GC_REFCOUNT(aht)--; + } + efree(Z_REF(params[0])); + zend_string_free(Z_STR(function_name)); + } } /* }}} */ #define SPL_ARRAY_METHOD(cname, fname, use_arg) \ diff --git a/ext/standard/array.c b/ext/standard/array.c index 4ff373a0b02..289870ac1f2 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -1035,38 +1035,31 @@ static int php_array_user_compare(const void *a, const void *b) /* {{{ */ static void php_usort(INTERNAL_FUNCTION_PARAMETERS, compare_func_t compare_func, zend_bool renumber) /* {{{ */ { zval *array; - zend_refcounted *arr; + zend_array *arr; zend_bool retval; PHP_ARRAY_CMP_FUNC_VARS; PHP_ARRAY_CMP_FUNC_BACKUP(); - if (zend_parse_parameters(ZEND_NUM_ARGS(), "a/f", &array, &BG(user_compare_fci), &BG(user_compare_fci_cache)) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS(), "af", &array, &BG(user_compare_fci), &BG(user_compare_fci_cache)) == FAILURE) { PHP_ARRAY_CMP_FUNC_RESTORE(); return; } - /* Increase reference counter, so the attempts to modify the array in user - * comparison function will create a copy of array and won't affect the - * original array. The fact of modification is detected by comparing the - * zend_array pointer. The result of sorting in such case is undefined and - * the function returns FALSE. - */ - Z_ADDREF_P(array); - arr = Z_COUNTED_P(array); - - retval = zend_hash_sort(Z_ARRVAL_P(array), compare_func, renumber) != FAILURE; - - if (arr != Z_COUNTED_P(array)) { - php_error_docref(NULL, E_WARNING, "Array was modified by the user comparison function"); - if (--GC_REFCOUNT(arr) <= 0) { - _zval_dtor_func(arr ZEND_FILE_LINE_CC); - } - retval = 0; - } else { - Z_DELREF_P(array); + arr = Z_ARR_P(array); + if (zend_hash_num_elements(arr) == 0) { + PHP_ARRAY_CMP_FUNC_RESTORE(); + RETURN_TRUE; } + /* Copy array, so the in-place modifications will not be visible to the callback function */ + arr = zend_array_dup(arr); + + retval = zend_hash_sort(arr, compare_func, renumber) != FAILURE; + + zval_ptr_dtor(array); + ZVAL_ARR(array, arr); + PHP_ARRAY_CMP_FUNC_RESTORE(); RETURN_BOOL(retval); } diff --git a/ext/standard/tests/array/bug71334.phpt b/ext/standard/tests/array/bug71334.phpt new file mode 100644 index 00000000000..7a37d0953a4 --- /dev/null +++ b/ext/standard/tests/array/bug71334.phpt @@ -0,0 +1,38 @@ +--TEST-- +Bug #71334: Cannot access array keys while uksort() +--FILE-- + [1], + '-' => [2], + 'bar-test' => [3] + ]; + + private function _mySort($x, $y) + { + if (!isset($this->a[$x])) { + throw new Exception('Missing X: "' . $x . '"'); + } + + if (!isset($this->a[$y])) { + throw new Exception('Missing Y: "' . $y . '"'); + } + + return $x < $y; + } + + public function __construct() + { + uksort($this->a, [$this, '_mySort']); + } +} + +new myClass(); +echo "Done"; + +?> +--EXPECT-- +Done diff --git a/ext/standard/tests/array/unexpected_array_mod_bug.phpt b/ext/standard/tests/array/unexpected_array_mod_bug.phpt index 58f22492054..2762ebd8309 100644 --- a/ext/standard/tests/array/unexpected_array_mod_bug.phpt +++ b/ext/standard/tests/array/unexpected_array_mod_bug.phpt @@ -4,7 +4,7 @@ Crash when function parameter modified via reference $b; } $my_var = array(1 => "entry_1", 2 => "entry_2", @@ -12,10 +12,19 @@ $my_var = array(1 => "entry_1", 4 => "entry_4", 5 => "entry_5"); usort($my_var, "usercompare"); +var_dump($my_var); -echo "Done.\n"; ?> ---EXPECTF-- - -Warning: usort(): Array was modified by the user comparison function in %s on line %d -Done. +--EXPECT-- +array(5) { + [0]=> + string(7) "entry_1" + [1]=> + string(7) "entry_2" + [2]=> + string(7) "entry_3" + [3]=> + string(7) "entry_4" + [4]=> + string(7) "entry_5" +} diff --git a/ext/standard/tests/array/unexpected_array_mod_bug_variation1.phpt b/ext/standard/tests/array/unexpected_array_mod_bug_variation1.phpt new file mode 100644 index 00000000000..b5a1ee24d59 --- /dev/null +++ b/ext/standard/tests/array/unexpected_array_mod_bug_variation1.phpt @@ -0,0 +1,33 @@ +--TEST-- +Crash when function parameter modified via reference while keeping orig refcount +--FILE-- + "entry_1", + 2 => "entry_2", + 3 => "entry_3", + 4 => "entry_4", + 5 => "entry_5" +); +usort($array, function($a, $b) use (&$array, &$ref) { + unset($array[2]); + $ref = $array; + return $a <=> $b; +}); +var_dump($array); + +?> +--EXPECT-- +array(5) { + [0]=> + string(7) "entry_1" + [1]=> + string(7) "entry_2" + [2]=> + string(7) "entry_3" + [3]=> + string(7) "entry_4" + [4]=> + string(7) "entry_5" +} From cef40c0c3fe05beb58ed8d4bc8bbf9658ab64a71 Mon Sep 17 00:00:00 2001 From: Lior Kaplan Date: Thu, 31 Mar 2016 00:52:53 +0300 Subject: [PATCH 6/9] Align NEWS entry format --- NEWS | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 20cb8767623..e72c7ca911d 100644 --- a/NEWS +++ b/NEWS @@ -21,8 +21,8 @@ PHP NEWS (Daniel kalaspuffar, Julien) - Postgres: - . Fixed bug #71820 (pg_fetch_object binds parameters before - call constructor). (Anatol) + . Fixed bug #71820 (pg_fetch_object binds parameters before call + constructor). (Anatol) - SPL: . Fixed bug #67582 (Cloned SplObjectStorage with overwritten getHash fails @@ -63,7 +63,7 @@ PHP NEWS name). (Stas) - PDO_DBlib: - . Bug #54648 (PDO::MSSQL forces format of datetime fields). + . Fixed bug #54648 (PDO::MSSQL forces format of datetime fields). (steven dot lambeth at gmx dot de, Anatol) - Phar: From 3b26af59d413ce599a5f0361aa3d132d5652cb3a Mon Sep 17 00:00:00 2001 From: Lior Kaplan Date: Thu, 31 Mar 2016 01:01:11 +0300 Subject: [PATCH 7/9] Align NEWS entry format --- NEWS | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index b8e4eefe090..b81998b5d26 100644 --- a/NEWS +++ b/NEWS @@ -33,8 +33,8 @@ PHP NEWS (Daniel kalaspuffar, Julien) - Postgres: - . Fixed bug #71820 (pg_fetch_object binds parameters before - call constructor). (Anatol) + . Fixed bug #71820 (pg_fetch_object binds parameters before call + constructor). (Anatol) - SPL: . Fixed bug #71838 (Deserializing serialized SPLObjectStorage-Object can't @@ -117,8 +117,7 @@ PHP NEWS (steven dot lambeth at gmx dot de, Anatol) - Phar: - . Fixed bug #71625 (Crash in php7.dll with bad phar filename). - (Anatol) + . Fixed bug #71625 (Crash in php7.dll with bad phar filename). (Anatol) . Fixed bug #71317 (PharData fails to open specific file). (Jos Elstgeest) . Fixed bug #71860 (Invalid memory write in phar on filename with \0 in name). (Stas) @@ -127,7 +126,7 @@ PHP NEWS . Fixed crash when advancing (except step) inside an internal function. (Bob) - Session: - . Fixed Bug #71683 (Null pointer dereference in zend_hash_str_find_bucket). + . Fixed bug #71683 (Null pointer dereference in zend_hash_str_find_bucket). (Yasuo) - SNMP: From ed707a521738fa7269b1992a6738bfef44662f46 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Thu, 31 Mar 2016 01:29:05 +0200 Subject: [PATCH 8/9] fix test to not to cause false positives --- ext/fileinfo/tests/bug68996.phpt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ext/fileinfo/tests/bug68996.phpt b/ext/fileinfo/tests/bug68996.phpt index da208d35bcc..214e52fa6f7 100644 --- a/ext/fileinfo/tests/bug68996.phpt +++ b/ext/fileinfo/tests/bug68996.phpt @@ -1,11 +1,14 @@ --TEST-- Bug #68996 (Invalid free of CG(interned_empty_string)) --SKIPIF-- + --INI-- html_errors=1 ---ENV-- -USE_ZEND_ALLOC=0 --FILE-- Date: Thu, 31 Mar 2016 01:33:38 +0200 Subject: [PATCH 9/9] fix borked mainstream patch --- ext/fileinfo/libmagic/funcs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/fileinfo/libmagic/funcs.c b/ext/fileinfo/libmagic/funcs.c index def2f7b31bc..b976ac9a49b 100644 --- a/ext/fileinfo/libmagic/funcs.c +++ b/ext/fileinfo/libmagic/funcs.c @@ -414,7 +414,7 @@ file_check_mem(struct magic_set *ms, unsigned int level) size_t len; if (level >= ms->c.len) { - len = (ms->c.len += 20 + level) * sizeof(*ms->c.li); + len = (ms->c.len = 20 + level) * sizeof(*ms->c.li); ms->c.li = CAST(struct level_info *, (ms->c.li == NULL) ? emalloc(len) : erealloc(ms->c.li, len));