From 2e157c527508c3cfa85bdabffe0560f2e50abf18 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Sun, 6 Dec 2015 14:07:39 -0800 Subject: [PATCH 01/16] typofix --- NEWS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS b/NEWS index d5b50167634..d2a2f95b9a0 100644 --- a/NEWS +++ b/NEWS @@ -8,7 +8,7 @@ PHP NEWS - Phar: . Fixed bug #69720 (Null pointer dereference in phar_get_fp_offset()). (Stas) - . FIxed bug #70433 (Uninitialized pointer in phar_make_dirstream when zip + . Fixed bug #70433 (Uninitialized pointer in phar_make_dirstream when zip entry filename is "/"). (Stas) 03 Sep 2015, PHP 5.5.29 From 4bb422343f29f06b7081323844d9b52e1a71e4a5 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 7 Dec 2015 23:30:49 -0800 Subject: [PATCH 02/16] Fix bug #70976: fix boundary check on gdImageRotateInterpolated --- NEWS | 4 ++++ ext/gd/libgd/gd_interpolation.c | 2 +- ext/gd/tests/bug70976.phpt | 13 +++++++++++++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 ext/gd/tests/bug70976.phpt diff --git a/NEWS b/NEWS index d2a2f95b9a0..d9fcf14df48 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,10 @@ PHP NEWS ?? ??? 2015, PHP 5.5.31 +- GD: + . Fixed bug #70976 (Memory Read via gdImageRotateInterpolated Array Index + Out of Bounds). (emmanuel dot law at gmail dot com). + 01 Oct 2015, PHP 5.5.30 - Phar: diff --git a/ext/gd/libgd/gd_interpolation.c b/ext/gd/libgd/gd_interpolation.c index 65e2360776b..efb584c1e4c 100644 --- a/ext/gd/libgd/gd_interpolation.c +++ b/ext/gd/libgd/gd_interpolation.c @@ -2154,7 +2154,7 @@ gdImagePtr gdImageRotateInterpolated(const gdImagePtr src, const float angle, in { const int angle_rounded = (int)floor(angle * 100); - if (bgcolor < 0) { + if (bgcolor < 0 || bgcolor >= gdMaxColors) { return NULL; } diff --git a/ext/gd/tests/bug70976.phpt b/ext/gd/tests/bug70976.phpt new file mode 100644 index 00000000000..23af4eedc74 --- /dev/null +++ b/ext/gd/tests/bug70976.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #70976 (Memory Read via gdImageRotateInterpolated Array Index Out of Bounds) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +bool(false) \ No newline at end of file From be19dbcb84fea0001e53cea2732c00de7ae6c371 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Tue, 8 Dec 2015 00:10:07 -0800 Subject: [PATCH 03/16] Fixed bug #70755: fpm_log.c memory leak and buffer overflow --- NEWS | 3 +++ sapi/fpm/fpm/fpm_log.c | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/NEWS b/NEWS index d9fcf14df48..f29a710c759 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,9 @@ PHP NEWS ?? ??? 2015, PHP 5.5.31 +- FPM: + . Fixed bug #70755 (fpm_log.c memory leak and buffer overflow). (Stas) + - GD: . Fixed bug #70976 (Memory Read via gdImageRotateInterpolated Array Index Out of Bounds). (emmanuel dot law at gmail dot com). diff --git a/sapi/fpm/fpm/fpm_log.c b/sapi/fpm/fpm/fpm_log.c index b0bf32ac165..187fe9bd07e 100644 --- a/sapi/fpm/fpm/fpm_log.c +++ b/sapi/fpm/fpm/fpm_log.c @@ -448,6 +448,11 @@ int fpm_log_write(char *log_format TSRMLS_DC) /* {{{ */ b += len2; len += len2; } + if (len >= FPM_LOG_BUFFER) { + zlog(ZLOG_NOTICE, "the log buffer is full (%d). The access log request has been truncated.", FPM_LOG_BUFFER); + len = FPM_LOG_BUFFER; + break; + } continue; } From 4df84a648ec62b17bd8f8359452f8defd1026167 Mon Sep 17 00:00:00 2001 From: Julien Pauli Date: Tue, 22 Dec 2015 14:28:19 +0100 Subject: [PATCH 04/16] Fixed #70728 --- ext/xmlrpc/tests/bug70728.phpt | 30 ++++++++++++++++++++++++++++++ ext/xmlrpc/xmlrpc-epi-php.c | 13 +++++++++++-- 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 ext/xmlrpc/tests/bug70728.phpt diff --git a/ext/xmlrpc/tests/bug70728.phpt b/ext/xmlrpc/tests/bug70728.phpt new file mode 100644 index 00000000000..5510c339361 --- /dev/null +++ b/ext/xmlrpc/tests/bug70728.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #70728 (Type Confusion Vulnerability in PHP_to_XMLRPC_worker) +--SKIPIF-- + +--FILE-- +xmlrpc_type = 'base64'; +$obj->scalar = 0x1122334455; +var_dump(xmlrpc_encode($obj)); +var_dump($obj); +?> +--EXPECTF-- +string(135) " + + + + NzM1ODgyMjkyMDU= + + + +" +object(stdClass)#1 (2) { + ["xmlrpc_type"]=> + string(6) "base64" + ["scalar"]=> + int(73588229205) +} diff --git a/ext/xmlrpc/xmlrpc-epi-php.c b/ext/xmlrpc/xmlrpc-epi-php.c index 613892ce24e..6c764347f52 100644 --- a/ext/xmlrpc/xmlrpc-epi-php.c +++ b/ext/xmlrpc/xmlrpc-epi-php.c @@ -532,7 +532,16 @@ static XMLRPC_VALUE PHP_to_XMLRPC_worker (const char* key, zval* in_val, int dep xReturn = XMLRPC_CreateValueEmpty(); XMLRPC_SetValueID(xReturn, key, 0); } else { - xReturn = XMLRPC_CreateValueBase64(key, Z_STRVAL_P(val), Z_STRLEN_P(val)); + if (Z_TYPE_P(val) != IS_STRING) { + zval *newvalue; + ALLOC_INIT_ZVAL(newvalue); + MAKE_COPY_ZVAL(&val, newvalue); + convert_to_string(newvalue); + xReturn = XMLRPC_CreateValueBase64(key, Z_STRVAL_P(newvalue), Z_STRLEN_P(newvalue)); + zval_ptr_dtor(&newvalue); + } else { + xReturn = XMLRPC_CreateValueBase64(key, Z_STRVAL_P(val), Z_STRLEN_P(val)); + } } break; case xmlrpc_datetime: @@ -1452,7 +1461,7 @@ XMLRPC_VALUE_TYPE get_zval_xmlrpc_type(zval* value, zval** newvalue) /* {{{ */ if (newvalue) { zval** val; - if ((type == xmlrpc_base64 && Z_TYPE_P(value) != IS_NULL) || type == xmlrpc_datetime) { + if ((type == xmlrpc_base64 && Z_TYPE_P(value) == IS_OBJECT) || type == xmlrpc_datetime) { if (zend_hash_find(Z_OBJPROP_P(value), OBJECT_VALUE_ATTR, sizeof(OBJECT_VALUE_ATTR), (void**) &val) == SUCCESS) { *newvalue = *val; } From 1785d2b805f64eaaacf98c14c9e13107bf085ab1 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 28 Dec 2015 12:42:44 -0800 Subject: [PATCH 05/16] Fixed bug #70741: Session WDDX Packet Deserialization Type Confusion Vulnerability --- NEWS | 4 + ext/wddx/tests/bug70741.phpt | 26 +++++++ ext/wddx/wddx.c | 139 ++++++++++++++++++----------------- 3 files changed, 101 insertions(+), 68 deletions(-) create mode 100644 ext/wddx/tests/bug70741.phpt diff --git a/NEWS b/NEWS index f29a710c759..67fbcae449a 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,10 @@ PHP NEWS . Fixed bug #70976 (Memory Read via gdImageRotateInterpolated Array Index Out of Bounds). (emmanuel dot law at gmail dot com). +- WDDX: + . Fixed bug #70741 (Session WDDX Packet Deserialization Type Confusion + Vulnerability). (taoguangchen at icloud dot com) + 01 Oct 2015, PHP 5.5.30 - Phar: diff --git a/ext/wddx/tests/bug70741.phpt b/ext/wddx/tests/bug70741.phpt new file mode 100644 index 00000000000..9c7e09b48b3 --- /dev/null +++ b/ext/wddx/tests/bug70741.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #70741 (Session WDDX Packet Deserialization Type Confusion Vulnerability) +--SKIPIF-- + +--FILE-- + + +
+ + $hashtable + +"; +session_decode($wddx); +?> +DONE +--EXPECTF-- + +Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s on line %d +DONE \ No newline at end of file diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c index 45beaece3a3..801762033c2 100644 --- a/ext/wddx/wddx.c +++ b/ext/wddx/wddx.c @@ -72,7 +72,7 @@ stack->varname = NULL; \ } else \ ent.varname = NULL; \ - + static int le_wddx; typedef struct { @@ -171,7 +171,7 @@ zend_module_entry wddx_module_entry = { /* }}} */ /* {{{ wddx_stack_init - */ + */ static int wddx_stack_init(wddx_stack *stack) { stack->top = 0; @@ -239,7 +239,7 @@ static int wddx_stack_destroy(wddx_stack *stack) efree(((st_entry *)stack->elements[i])->varname); } efree(stack->elements[i]); - } + } efree(stack->elements); } return SUCCESS; @@ -270,16 +270,16 @@ PS_SERIALIZER_ENCODE_FUNC(wddx) php_wddx_packet_start(packet, NULL, 0); php_wddx_add_chunk_static(packet, WDDX_STRUCT_S); - + PS_ENCODE_LOOP( php_wddx_serialize_var(packet, *struc, key, key_length TSRMLS_CC); ); - + php_wddx_add_chunk_static(packet, WDDX_STRUCT_E); php_wddx_packet_end(packet); *newstr = php_wddx_gather(packet); php_wddx_destructor(packet); - + if (newlen) { *newlen = strlen(*newstr); } @@ -304,11 +304,14 @@ PS_SERIALIZER_DECODE_FUNC(wddx) if (vallen == 0) { return SUCCESS; } - + MAKE_STD_ZVAL(retval); if ((ret = php_wddx_deserialize_ex((char *)val, vallen, retval)) == SUCCESS) { - + if (Z_TYPE_P(retval) != IS_ARRAY) { + zval_ptr_dtor(&retval); + return FAILURE; + } for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(retval)); zend_hash_get_current_data(Z_ARRVAL_P(retval), (void **) &ent) == SUCCESS; zend_hash_move_forward(Z_ARRVAL_P(retval))) { @@ -343,7 +346,7 @@ PHP_MINIT_FUNCTION(wddx) php_session_register_serializer("wddx", PS_SERIALIZER_ENCODE_NAME(wddx), PS_SERIALIZER_DECODE_NAME(wddx)); -#endif +#endif return SUCCESS; } @@ -387,7 +390,7 @@ void php_wddx_packet_start(wddx_packet *packet, char *comment, int comment_len) void php_wddx_packet_end(wddx_packet *packet) { php_wddx_add_chunk_static(packet, WDDX_DATA_E); - php_wddx_add_chunk_static(packet, WDDX_PACKET_E); + php_wddx_add_chunk_static(packet, WDDX_PACKET_E); } /* }}} */ @@ -423,14 +426,14 @@ static void php_wddx_serialize_number(wddx_packet *packet, zval *var) { char tmp_buf[WDDX_BUF_LEN]; zval tmp; - + tmp = *var; zval_copy_ctor(&tmp); convert_to_string(&tmp); snprintf(tmp_buf, sizeof(tmp_buf), WDDX_NUMBER, Z_STRVAL(tmp)); zval_dtor(&tmp); - php_wddx_add_chunk(packet, tmp_buf); + php_wddx_add_chunk(packet, tmp_buf); } /* }}} */ @@ -473,7 +476,7 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj) if (call_user_function_ex(CG(function_table), &obj, fname, &retval, 0, 0, 1, NULL TSRMLS_CC) == SUCCESS) { if (retval && (sleephash = HASH_OF(retval))) { PHP_CLASS_ATTRIBUTES; - + PHP_SET_CLASS_ATTRIBUTES(obj); php_wddx_add_chunk_static(packet, WDDX_STRUCT_S); @@ -487,7 +490,7 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj) PHP_CLEANUP_CLASS_ATTRIBUTES(); objhash = HASH_OF(obj); - + for (zend_hash_internal_pointer_reset(sleephash); zend_hash_get_current_data(sleephash, (void **)&varname) == SUCCESS; zend_hash_move_forward(sleephash)) { @@ -500,7 +503,7 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj) php_wddx_serialize_var(packet, *ent, Z_STRVAL_PP(varname), Z_STRLEN_PP(varname) TSRMLS_CC); } } - + php_wddx_add_chunk_static(packet, WDDX_STRUCT_E); } } else { @@ -519,7 +522,7 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj) php_wddx_add_chunk_static(packet, WDDX_VAR_E); PHP_CLEANUP_CLASS_ATTRIBUTES(); - + objhash = HASH_OF(obj); for (zend_hash_internal_pointer_reset(objhash); zend_hash_get_current_data(objhash, (void**)&ent) == SUCCESS; @@ -530,7 +533,7 @@ static void php_wddx_serialize_object(wddx_packet *packet, zval *obj) if (zend_hash_get_current_key_ex(objhash, &key, &key_len, &idx, 0, NULL) == HASH_KEY_IS_STRING) { const char *class_name, *prop_name; - + zend_unmangle_property_name(key, key_len-1, &class_name, &prop_name); php_wddx_serialize_var(packet, *ent, prop_name, strlen(prop_name)+1 TSRMLS_CC); } else { @@ -613,7 +616,7 @@ static void php_wddx_serialize_array(wddx_packet *packet, zval *arr) php_wddx_serialize_var(packet, *ent, NULL, 0 TSRMLS_CC); } } - + if (is_struct) { php_wddx_add_chunk_static(packet, WDDX_STRUCT_E); } else { @@ -639,12 +642,12 @@ void php_wddx_serialize_var(wddx_packet *packet, zval *var, char *name, int name efree(tmp_buf); efree(name_esc); } - + switch(Z_TYPE_P(var)) { case IS_STRING: php_wddx_serialize_string(packet, var TSRMLS_CC); break; - + case IS_LONG: case IS_DOUBLE: php_wddx_serialize_number(packet, var); @@ -657,14 +660,14 @@ void php_wddx_serialize_var(wddx_packet *packet, zval *var, char *name, int name case IS_NULL: php_wddx_serialize_unset(packet); break; - + case IS_ARRAY: ht = Z_ARRVAL_P(var); if (ht->nApplyCount > 1) { php_error_docref(NULL TSRMLS_CC, E_RECOVERABLE_ERROR, "WDDX doesn't support circular references"); return; } - ht->nApplyCount++; + ht->nApplyCount++; php_wddx_serialize_array(packet, var); ht->nApplyCount--; break; @@ -680,7 +683,7 @@ void php_wddx_serialize_var(wddx_packet *packet, zval *var, char *name, int name ht->nApplyCount--; break; } - + if (name) { php_wddx_add_chunk_static(packet, WDDX_VAR_E); } @@ -702,12 +705,12 @@ static void php_wddx_add_var(wddx_packet *packet, zval *name_var) if (zend_hash_find(EG(active_symbol_table), Z_STRVAL_P(name_var), Z_STRLEN_P(name_var)+1, (void**)&val) != FAILURE) { php_wddx_serialize_var(packet, *val, Z_STRVAL_P(name_var), Z_STRLEN_P(name_var) TSRMLS_CC); - } + } } else if (Z_TYPE_P(name_var) == IS_ARRAY || Z_TYPE_P(name_var) == IS_OBJECT) { int is_array = Z_TYPE_P(name_var) == IS_ARRAY; - + target_hash = HASH_OF(name_var); - + if (is_array && target_hash->nApplyCount > 1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected"); return; @@ -737,10 +740,10 @@ static void php_wddx_push_element(void *user_data, const XML_Char *name, const X { st_entry ent; wddx_stack *stack = (wddx_stack *)user_data; - + if (!strcmp(name, EL_PACKET)) { int i; - + if (atts) for (i=0; atts[i]; i++) { if (!strcmp(atts[i], EL_VERSION)) { /* nothing for now */ @@ -749,7 +752,7 @@ static void php_wddx_push_element(void *user_data, const XML_Char *name, const X } else if (!strcmp(name, EL_STRING)) { ent.type = ST_STRING; SET_STACK_VARNAME; - + ALLOC_ZVAL(ent.data); INIT_PZVAL(ent.data); Z_TYPE_P(ent.data) = IS_STRING; @@ -759,7 +762,7 @@ static void php_wddx_push_element(void *user_data, const XML_Char *name, const X } else if (!strcmp(name, EL_BINARY)) { ent.type = ST_BINARY; SET_STACK_VARNAME; - + ALLOC_ZVAL(ent.data); INIT_PZVAL(ent.data); Z_TYPE_P(ent.data) = IS_STRING; @@ -768,7 +771,7 @@ static void php_wddx_push_element(void *user_data, const XML_Char *name, const X wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry)); } else if (!strcmp(name, EL_CHAR)) { int i; - + if (atts) for (i = 0; atts[i]; i++) { if (!strcmp(atts[i], EL_CHAR_CODE) && atts[++i] && atts[i][0]) { char tmp_buf[2]; @@ -781,7 +784,7 @@ static void php_wddx_push_element(void *user_data, const XML_Char *name, const X } else if (!strcmp(name, EL_NUMBER)) { ent.type = ST_NUMBER; SET_STACK_VARNAME; - + ALLOC_ZVAL(ent.data); INIT_PZVAL(ent.data); Z_TYPE_P(ent.data) = IS_LONG; @@ -810,12 +813,12 @@ static void php_wddx_push_element(void *user_data, const XML_Char *name, const X ALLOC_ZVAL(ent.data); INIT_PZVAL(ent.data); ZVAL_NULL(ent.data); - + wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry)); } else if (!strcmp(name, EL_ARRAY)) { ent.type = ST_ARRAY; SET_STACK_VARNAME; - + ALLOC_ZVAL(ent.data); array_init(ent.data); INIT_PZVAL(ent.data); @@ -823,14 +826,14 @@ static void php_wddx_push_element(void *user_data, const XML_Char *name, const X } else if (!strcmp(name, EL_STRUCT)) { ent.type = ST_STRUCT; SET_STACK_VARNAME; - + ALLOC_ZVAL(ent.data); array_init(ent.data); INIT_PZVAL(ent.data); wddx_stack_push((wddx_stack *)stack, &ent, sizeof(st_entry)); } else if (!strcmp(name, EL_VAR)) { int i; - + if (atts) for (i = 0; atts[i]; i++) { if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) { stack->varname = estrdup(atts[i]); @@ -885,13 +888,13 @@ static void php_wddx_push_element(void *user_data, const XML_Char *name, const X if (!strcmp(atts[i], EL_NAME) && atts[++i] && atts[i][0]) { st_entry *recordset; zval **field; - + if (wddx_stack_top(stack, (void**)&recordset) == SUCCESS && recordset->type == ST_RECORDSET && zend_hash_find(Z_ARRVAL_P(recordset->data), (char*)atts[i], strlen(atts[i])+1, (void**)&field) == SUCCESS) { ent.data = *field; } - + break; } } @@ -900,7 +903,7 @@ static void php_wddx_push_element(void *user_data, const XML_Char *name, const X } else if (!strcmp(name, EL_DATETIME)) { ent.type = ST_DATETIME; SET_STACK_VARNAME; - + ALLOC_ZVAL(ent.data); INIT_PZVAL(ent.data); Z_TYPE_P(ent.data) = IS_LONG; @@ -962,14 +965,14 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name) if (stack->top > 1) { stack->top--; wddx_stack_top(stack, (void**)&ent2); - + /* if non-existent field */ if (ent2->type == ST_FIELD && ent2->data == NULL) { zval_ptr_dtor(&ent1->data); efree(ent1); return; } - + if (Z_TYPE_P(ent2->data) == IS_ARRAY || Z_TYPE_P(ent2->data) == IS_OBJECT) { target_hash = HASH_OF(ent2->data); @@ -988,7 +991,7 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name) /* Initialize target object */ MAKE_STD_ZVAL(obj); object_init_ex(obj, *pce); - + /* Merge current hashtable with object's default properties */ zend_hash_merge(Z_OBJPROP_P(obj), Z_ARRVAL_P(ent2->data), @@ -1001,15 +1004,15 @@ static void php_wddx_pop_element(void *user_data, const XML_Char *name) /* Clean up old array entry */ zval_ptr_dtor(&ent2->data); - + /* Set stack entry to point to the newly created object */ ent2->data = obj; - + /* Clean up class name var entry */ zval_ptr_dtor(&ent1->data); } else if (Z_TYPE_P(ent2->data) == IS_OBJECT) { zend_class_entry *old_scope = EG(scope); - + EG(scope) = Z_OBJCE_P(ent2->data); Z_DELREF_P(ent1->data); add_property_zval(ent2->data, ent1->varname, ent1->data); @@ -1048,7 +1051,7 @@ static void php_wddx_process_data(void *user_data, const XML_Char *s, int len) if (!wddx_stack_is_empty(stack) && !stack->done) { wddx_stack_top(stack, (void**)&ent); switch (Z_TYPE_P(ent)) { - case ST_STRING: + case ST_STRING: if (Z_STRLEN_P(ent->data) == 0) { STR_FREE(Z_STRVAL_P(ent->data)); Z_STRVAL_P(ent->data) = estrndup(s, len); @@ -1127,16 +1130,16 @@ int php_wddx_deserialize_ex(char *value, int vallen, zval *return_value) XML_Parser parser; st_entry *ent; int retval; - + wddx_stack_init(&stack); parser = XML_ParserCreate("UTF-8"); XML_SetUserData(parser, &stack); XML_SetElementHandler(parser, php_wddx_push_element, php_wddx_pop_element); XML_SetCharacterDataHandler(parser, php_wddx_process_data); - + XML_Parse(parser, value, vallen, 1); - + XML_ParserFree(parser); if (stack.top == 1) { @@ -1147,7 +1150,7 @@ int php_wddx_deserialize_ex(char *value, int vallen, zval *return_value) } else { retval = FAILURE; } - + wddx_stack_destroy(&stack); return retval; @@ -1162,17 +1165,17 @@ PHP_FUNCTION(wddx_serialize_value) char *comment = NULL; int comment_len = 0; wddx_packet *packet; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|s", &var, &comment, &comment_len) == FAILURE) { return; } - + packet = php_wddx_constructor(); php_wddx_packet_start(packet, comment, comment_len); php_wddx_serialize_var(packet, var, NULL, 0 TSRMLS_CC); php_wddx_packet_end(packet); - + ZVAL_STRINGL(return_value, packet->c, packet->len, 1); smart_str_free(packet); efree(packet); @@ -1190,19 +1193,19 @@ PHP_FUNCTION(wddx_serialize_vars) if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", &args, &num_args) == FAILURE) { return; } - + packet = php_wddx_constructor(); php_wddx_packet_start(packet, NULL, 0); php_wddx_add_chunk_static(packet, WDDX_STRUCT_S); - + for (i=0; ic, packet->len, 1); @@ -1290,7 +1293,7 @@ PHP_FUNCTION(wddx_add_vars) zval ***args = NULL; zval *packet_id; wddx_packet *packet = NULL; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r+", &packet_id, &args, &num_args) == FAILURE) { return; } @@ -1299,12 +1302,12 @@ PHP_FUNCTION(wddx_add_vars) efree(args); RETURN_FALSE; } - + if (!packet) { efree(args); RETURN_FALSE; } - + for (i=0; i Date: Mon, 28 Dec 2015 14:46:35 -0800 Subject: [PATCH 06/16] Fixed bug #70661 (Use After Free Vulnerability in WDDX Packet Deserialization) --- NEWS | 2 ++ ext/wddx/tests/bug70661.phpt | 69 ++++++++++++++++++++++++++++++++++++ ext/wddx/wddx.c | 2 +- 3 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 ext/wddx/tests/bug70661.phpt diff --git a/NEWS b/NEWS index 67fbcae449a..f49c76a3312 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,8 @@ PHP NEWS Out of Bounds). (emmanuel dot law at gmail dot com). - WDDX: + . Fixed bug #70661 (Use After Free Vulnerability in WDDX Packet Deserialization). + (taoguangchen at icloud dot com) . Fixed bug #70741 (Session WDDX Packet Deserialization Type Confusion Vulnerability). (taoguangchen at icloud dot com) diff --git a/ext/wddx/tests/bug70661.phpt b/ext/wddx/tests/bug70661.phpt new file mode 100644 index 00000000000..e068c20a7a0 --- /dev/null +++ b/ext/wddx/tests/bug70661.phpt @@ -0,0 +1,69 @@ +--TEST-- +Bug #70661 (Use After Free Vulnerability in WDDX Packet Deserialization) +--SKIPIF-- + +--FILE-- + + +
+ + + + + + stdClass + + + + + + + +EOT; + +$y = wddx_deserialize($x); + +for ($i = 0; $i < 5; $i++) { + $v[$i] = $fakezval.$i; +} + +var_dump($y); + +function ptr2str($ptr) +{ + $out = ''; + + for ($i = 0; $i < 8; $i++) { + $out .= chr($ptr & 0xff); + $ptr >>= 8; + } + + return $out; +} +?> +DONE +--EXPECTF-- +array(1) { + [0]=> + array(1) { + ["ryat"]=> + array(2) { + ["php_class_name"]=> + string(8) "stdClass" + [0]=> + NULL + } + } +} +DONE \ No newline at end of file diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c index 801762033c2..b9dd1fa78ea 100644 --- a/ext/wddx/wddx.c +++ b/ext/wddx/wddx.c @@ -978,7 +978,7 @@ 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)) { + Z_TYPE_P(ent1->data) == IS_STRING && Z_STRLEN_P(ent1->data) && ent2->type == ST_STRUCT) { zend_bool incomplete_class = 0; zend_str_tolower(Z_STRVAL_P(ent1->data), Z_STRLEN_P(ent1->data)); From 2baeb167a08b0186a885208bdc8b5871f1681dc8 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 28 Dec 2015 23:44:14 -0800 Subject: [PATCH 07/16] Improve fix for bug #70976 --- ext/gd/libgd/gd_interpolation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/gd/libgd/gd_interpolation.c b/ext/gd/libgd/gd_interpolation.c index efb584c1e4c..eb35efb470f 100644 --- a/ext/gd/libgd/gd_interpolation.c +++ b/ext/gd/libgd/gd_interpolation.c @@ -2154,7 +2154,7 @@ gdImagePtr gdImageRotateInterpolated(const gdImagePtr src, const float angle, in { const int angle_rounded = (int)floor(angle * 100); - if (bgcolor < 0 || bgcolor >= gdMaxColors) { + if (bgcolor < 0 || (!src->trueColor && bgcolor >= gdMaxColors)) { return NULL; } From bc4baf608b69b1f6ba05aa136900c4467343592b Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 28 Dec 2015 14:46:35 -0800 Subject: [PATCH 08/16] Fixed bug #70661 (Use After Free Vulnerability in WDDX Packet Deserialization) Conflicts: ext/wddx/wddx.c --- ext/wddx/tests/bug70661.phpt | 69 ++++++++++++++++++++++++++++++++++++ ext/wddx/wddx.c | 2 +- 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 ext/wddx/tests/bug70661.phpt diff --git a/ext/wddx/tests/bug70661.phpt b/ext/wddx/tests/bug70661.phpt new file mode 100644 index 00000000000..e068c20a7a0 --- /dev/null +++ b/ext/wddx/tests/bug70661.phpt @@ -0,0 +1,69 @@ +--TEST-- +Bug #70661 (Use After Free Vulnerability in WDDX Packet Deserialization) +--SKIPIF-- + +--FILE-- + + +
+ + + + + + stdClass + + + + + + + +EOT; + +$y = wddx_deserialize($x); + +for ($i = 0; $i < 5; $i++) { + $v[$i] = $fakezval.$i; +} + +var_dump($y); + +function ptr2str($ptr) +{ + $out = ''; + + for ($i = 0; $i < 8; $i++) { + $out .= chr($ptr & 0xff); + $ptr >>= 8; + } + + return $out; +} +?> +DONE +--EXPECTF-- +array(1) { + [0]=> + array(1) { + ["ryat"]=> + array(2) { + ["php_class_name"]=> + string(8) "stdClass" + [0]=> + NULL + } + } +} +DONE \ No newline at end of file diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c index 66328900844..83b8f97294d 100644 --- a/ext/wddx/wddx.c +++ b/ext/wddx/wddx.c @@ -908,7 +908,7 @@ 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(ent1->data) == IS_STRING && Z_STRLEN(ent1->data)) { + Z_TYPE(ent1->data) == IS_STRING && Z_STRLEN(ent1->data) && ent2->type == ST_STRUCT) { zend_bool incomplete_class = 0; zend_str_tolower(Z_STRVAL(ent1->data), Z_STRLEN(ent1->data)); From ef4449a8e822ff6bfee96dbe48a64f6b43dcf040 Mon Sep 17 00:00:00 2001 From: Julien Pauli Date: Tue, 22 Dec 2015 14:28:19 +0100 Subject: [PATCH 09/16] Fixed #70728 Conflicts: ext/xmlrpc/xmlrpc-epi-php.c --- ext/xmlrpc/tests/bug70728.phpt | 30 ++++++++++++++++++++++++++++++ ext/xmlrpc/xmlrpc-epi-php.c | 12 ++++++++++-- 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 ext/xmlrpc/tests/bug70728.phpt diff --git a/ext/xmlrpc/tests/bug70728.phpt b/ext/xmlrpc/tests/bug70728.phpt new file mode 100644 index 00000000000..5510c339361 --- /dev/null +++ b/ext/xmlrpc/tests/bug70728.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #70728 (Type Confusion Vulnerability in PHP_to_XMLRPC_worker) +--SKIPIF-- + +--FILE-- +xmlrpc_type = 'base64'; +$obj->scalar = 0x1122334455; +var_dump(xmlrpc_encode($obj)); +var_dump($obj); +?> +--EXPECTF-- +string(135) " + + + + NzM1ODgyMjkyMDU= + + + +" +object(stdClass)#1 (2) { + ["xmlrpc_type"]=> + string(6) "base64" + ["scalar"]=> + int(73588229205) +} diff --git a/ext/xmlrpc/xmlrpc-epi-php.c b/ext/xmlrpc/xmlrpc-epi-php.c index f54a568202d..7eae7bf8fc7 100644 --- a/ext/xmlrpc/xmlrpc-epi-php.c +++ b/ext/xmlrpc/xmlrpc-epi-php.c @@ -514,7 +514,15 @@ static XMLRPC_VALUE PHP_to_XMLRPC_worker (const char* key, zval* in_val, int dep xReturn = XMLRPC_CreateValueEmpty(); XMLRPC_SetValueID(xReturn, key, 0); } else { - xReturn = XMLRPC_CreateValueBase64(key, Z_STRVAL(val), Z_STRLEN(val)); + if (Z_TYPE(val) != IS_STRING) { + zval newvalue; + ZVAL_DUP(&newvalue, &val); + convert_to_string(newvalue); + xReturn = XMLRPC_CreateValueBase64(key, Z_STRVAL(newvalue), Z_STRLEN(newvalue)); + zval_dtor(&newvalue); + } else { + xReturn = XMLRPC_CreateValueBase64(key, Z_STRVAL(val), Z_STRLEN(val)); + } } break; case xmlrpc_datetime: @@ -1357,7 +1365,7 @@ XMLRPC_VALUE_TYPE get_zval_xmlrpc_type(zval* value, zval* newvalue) /* {{{ */ if (newvalue) { zval* val; - if ((type == xmlrpc_base64 && Z_TYPE_P(value) != IS_NULL) || type == xmlrpc_datetime) { + if ((type == xmlrpc_base64 && Z_TYPE_P(value) == IS_OBJECT) || type == xmlrpc_datetime) { if ((val = zend_hash_str_find(Z_OBJPROP_P(value), OBJECT_VALUE_ATTR, sizeof(OBJECT_VALUE_ATTR) - 1)) != NULL) { ZVAL_COPY_VALUE(newvalue, val); } From b0285db4b70186abf830b5d9741b038545f8799b Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Mon, 4 Jan 2016 17:33:23 +0100 Subject: [PATCH 10/16] fix merge mistake --- ext/xmlrpc/xmlrpc-epi-php.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/xmlrpc/xmlrpc-epi-php.c b/ext/xmlrpc/xmlrpc-epi-php.c index 7eae7bf8fc7..dd39047bf00 100644 --- a/ext/xmlrpc/xmlrpc-epi-php.c +++ b/ext/xmlrpc/xmlrpc-epi-php.c @@ -517,7 +517,7 @@ static XMLRPC_VALUE PHP_to_XMLRPC_worker (const char* key, zval* in_val, int dep if (Z_TYPE(val) != IS_STRING) { zval newvalue; ZVAL_DUP(&newvalue, &val); - convert_to_string(newvalue); + convert_to_string(&newvalue); xReturn = XMLRPC_CreateValueBase64(key, Z_STRVAL(newvalue), Z_STRLEN(newvalue)); zval_dtor(&newvalue); } else { From 2eaa7556605ffc0d78c89965f5e905cf801207ef Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Tue, 8 Dec 2015 00:10:07 -0800 Subject: [PATCH 11/16] Fixed bug #70755: fpm_log.c memory leak and buffer overflow --- sapi/fpm/fpm/fpm_log.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sapi/fpm/fpm/fpm_log.c b/sapi/fpm/fpm/fpm_log.c index 86332c4c803..5aad9a08c9e 100644 --- a/sapi/fpm/fpm/fpm_log.c +++ b/sapi/fpm/fpm/fpm_log.c @@ -448,6 +448,11 @@ int fpm_log_write(char *log_format) /* {{{ */ b += len2; len += len2; } + if (len >= FPM_LOG_BUFFER) { + zlog(ZLOG_NOTICE, "the log buffer is full (%d). The access log request has been truncated.", FPM_LOG_BUFFER); + len = FPM_LOG_BUFFER; + break; + } continue; } From 84b8db597ae597abce1977ce64dcf231e71330f9 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 7 Dec 2015 23:30:49 -0800 Subject: [PATCH 12/16] Fix bug #70976: fix boundary check on gdImageRotateInterpolated --- ext/gd/libgd/gd_interpolation.c | 2 +- ext/gd/tests/bug70976.phpt | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 ext/gd/tests/bug70976.phpt diff --git a/ext/gd/libgd/gd_interpolation.c b/ext/gd/libgd/gd_interpolation.c index f70169dddcf..0f874ac4cbd 100644 --- a/ext/gd/libgd/gd_interpolation.c +++ b/ext/gd/libgd/gd_interpolation.c @@ -2162,7 +2162,7 @@ gdImagePtr gdImageRotateInterpolated(const gdImagePtr src, const float angle, in { const int angle_rounded = (int)floor(angle * 100); - if (bgcolor < 0) { + if (bgcolor < 0 || bgcolor >= gdMaxColors) { return NULL; } diff --git a/ext/gd/tests/bug70976.phpt b/ext/gd/tests/bug70976.phpt new file mode 100644 index 00000000000..23af4eedc74 --- /dev/null +++ b/ext/gd/tests/bug70976.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #70976 (Memory Read via gdImageRotateInterpolated Array Index Out of Bounds) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +bool(false) \ No newline at end of file From 82865dda71d436bc8a89f1e601ca6964f4cb54f5 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Mon, 28 Dec 2015 23:44:14 -0800 Subject: [PATCH 13/16] Improve fix for bug #70976 --- ext/gd/libgd/gd_interpolation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/gd/libgd/gd_interpolation.c b/ext/gd/libgd/gd_interpolation.c index 0f874ac4cbd..a946e04b4df 100644 --- a/ext/gd/libgd/gd_interpolation.c +++ b/ext/gd/libgd/gd_interpolation.c @@ -2162,7 +2162,7 @@ gdImagePtr gdImageRotateInterpolated(const gdImagePtr src, const float angle, in { const int angle_rounded = (int)floor(angle * 100); - if (bgcolor < 0 || bgcolor >= gdMaxColors) { + if (bgcolor < 0 || (!src->trueColor && bgcolor >= gdMaxColors)) { return NULL; } From cf1c50957b8169af01318df67bee42f8134cd708 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Mon, 4 Jan 2016 17:52:37 +0100 Subject: [PATCH 14/16] re-apply the patch from 1785d2b805f64eaaacf98c14c9e13107bf085ab1 too many conflicts to cherry-pick --- ext/wddx/tests/bug70741.phpt | 26 ++++++++++++++++++++++++++ ext/wddx/wddx.c | 4 ++++ 2 files changed, 30 insertions(+) create mode 100644 ext/wddx/tests/bug70741.phpt diff --git a/ext/wddx/tests/bug70741.phpt b/ext/wddx/tests/bug70741.phpt new file mode 100644 index 00000000000..9c7e09b48b3 --- /dev/null +++ b/ext/wddx/tests/bug70741.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #70741 (Session WDDX Packet Deserialization Type Confusion Vulnerability) +--SKIPIF-- + +--FILE-- + + +
+ + $hashtable + +"; +session_decode($wddx); +?> +DONE +--EXPECTF-- + +Warning: session_decode(): Failed to decode session object. Session has been destroyed in %s on line %d +DONE \ No newline at end of file diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c index 83b8f97294d..c0971f89745 100644 --- a/ext/wddx/wddx.c +++ b/ext/wddx/wddx.c @@ -298,6 +298,10 @@ PS_SERIALIZER_DECODE_FUNC(wddx) ZVAL_UNDEF(&retval); if ((ret = php_wddx_deserialize_ex(val, vallen, &retval)) == SUCCESS) { + if (Z_TYPE(retval) != IS_ARRAY) { + zval_dtor(&retval); + return FAILURE; + } ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL(retval), idx, key, ent) { if (key == NULL) { key = zend_long_to_str(idx); From af960fcba4b4b5845294d2679366da5eac601cf8 Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Tue, 5 Jan 2016 13:06:00 +0100 Subject: [PATCH 15/16] add NEWS entries for 7.0.2 --- NEWS | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/NEWS b/NEWS index cc43981a502..2eefcfb5642 100644 --- a/NEWS +++ b/NEWS @@ -69,10 +69,17 @@ PHP NEWS - Filter: . Fixed bug #71063 (filter_input(INPUT_ENV, ..) does not work). (Reeze Xia) +- FPM: + . Fixed bug #70755 (fpm_log.c memory leak and buffer overflow). (Stas) + - FTP: . Implemented FR #55651 (Option to ignore the returned FTP PASV address). (abrender at elitehosts dot com) +- GD: + . Fixed bug #70976 (Memory Read via gdImageRotateInterpolated Array Index + Out of Bounds). (emmanuel dot law at gmail dot com). + - Mbstring: . Fixed bug #71066 (mb_send_mail: Program terminated with signal SIGSEGV, Segmentation fault). (Laruence) @@ -97,6 +104,16 @@ PHP NEWS . Fixed bug #71153 (Performance Degradation in ArrayIterator with large arrays). (Nikita) +- WDDX: + . Fixed bug #70661 (Use After Free Vulnerability in WDDX Packet Deserialization). + (taoguangchen at icloud dot com) + . Fixed bug #70741 (Session WDDX Packet Deserialization Type Confusion + Vulnerability). (taoguangchen at icloud dot com) + +- XMLRPC + . Fixed bug #70728 (Type Confusion Vulnerability in PHP_to_XMLRPC_worker). + (Julien) + 17 Dec 2015, PHP 7.0.1 - Core: From 74dcbe12997132353fd75d0c14548cff5235329f Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Tue, 5 Jan 2016 19:28:24 -0800 Subject: [PATCH 16/16] Update NEWS --- NEWS | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/NEWS b/NEWS index f49c76a3312..ee0e9869bd2 100644 --- a/NEWS +++ b/NEWS @@ -2,7 +2,7 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ** PHP 5.5 is in security-only mode , please do not commit to this branch ** -?? ??? 2015, PHP 5.5.31 +07 Jan 2015, PHP 5.5.31 - FPM: . Fixed bug #70755 (fpm_log.c memory leak and buffer overflow). (Stas) @@ -17,6 +17,10 @@ PHP NEWS . Fixed bug #70741 (Session WDDX Packet Deserialization Type Confusion Vulnerability). (taoguangchen at icloud dot com) +- XMLRPC: + . Fixed bug #70728 (Type Confusion Vulnerability in PHP_to_XMLRPC_worker()). + (Julien) + 01 Oct 2015, PHP 5.5.30 - Phar: