Backported from 5.6.27 by Remi. From 19866fb76cf4c95d904ebb0e08592cf38303fae9 Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Thu, 1 Sep 2016 23:15:34 -0700 Subject: [PATCH] Fix various int size overflows. Add function for detection of string zvals with length that does not fit INT_MAX. --- Zend/zend_API.c | 61 ++++++++++++++--- Zend/zend_API.h | 14 ++++ Zend/zend_alloc.c | 9 +++ Zend/zend_alloc.h | 4 +- ext/imap/php_imap.c | 28 +++++--- ext/ldap/ldap.c | 2 +- ext/pcre/php_pcre.c | 14 ++-- ext/pgsql/pgsql.c | 186 +++++++++++++++++++++++++------------------------- ext/standard/string.c | 23 +++---- ext/xml/xml.c | 4 +- ext/zlib/zlib.c | 8 +-- 11 files changed, 210 insertions(+), 143 deletions(-) diff --git a/Zend/zend_API.h b/Zend/zend_API.h index e17be4c..3e191b6 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -642,6 +642,21 @@ END_EXTERN_C() #define RETURN_FALSE { RETVAL_FALSE; return; } #define RETURN_TRUE { RETVAL_TRUE; return; } +/* Check that returned string length fits int */ +#define RETVAL_STRINGL_CHECK(s, len, dup) do { \ + size_t __len = (len); \ + if (UNEXPECTED(__len > INT_MAX)) { \ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "String too long, max is %d", INT_MAX); \ + if(!(dup)) { \ + efree((s)); \ + } \ + RETURN_FALSE; \ + } \ + RETVAL_STRINGL((s), __len, (dup)); \ +} while (0) + + + #define SET_VAR_STRING(n, v) { \ { \ zval *var; \ From 96a8cf8e1b5dc1b0c708bb5574e0d6727cc56d9e Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Tue, 11 Oct 2016 13:30:52 -0700 Subject: [PATCH] Fix bug #73293 - NULL pointer dereference in SimpleXMLElement::asXML() --- Zend/zend_API.h | 2 +- ext/simplexml/simplexml.c | 33 +++++++++++++++++++++++---------- 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/Zend/zend_API.h b/Zend/zend_API.h index c57c003..dadeaf5 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -652,7 +652,7 @@ END_EXTERN_C() } \ RETURN_FALSE; \ } \ - RETVAL_STRINGL((s), __len, (dup)); \ + RETVAL_STRINGL((s), (int)__len, (dup)); \ } while (0) diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 07fc654..d7077fc 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -989,7 +989,7 @@ static inline char * sxe_xmlNodeListGetString(xmlDocPtr doc, xmlNodePtr list, in { xmlChar *tmp = xmlNodeListGetString(doc, list, inLine); char *res; - + if (tmp) { res = estrdup((char*)tmp); xmlFree(tmp); @@ -1147,7 +1147,7 @@ static HashTable * sxe_get_prop_hash(zval *object, int is_debug TSRMLS_DC) /* {{ } else { if (node->type == XML_TEXT_NODE) { const xmlChar *cur = node->content; - + if (*cur != 0) { MAKE_STD_ZVAL(value); ZVAL_STRING(value, sxe_xmlNodeListGetString(node->doc, node, 1), 0); @@ -1198,7 +1198,7 @@ next_iter: static HashTable * sxe_get_gc(zval *object, zval ***table, int *n TSRMLS_DC) /* {{{ */ { php_sxe_object *sxe; sxe = php_sxe_fetch_object(object TSRMLS_CC); - + *table = NULL; *n = 0; return sxe->properties; @@ -1302,7 +1302,7 @@ SXE_METHOD(xpath) result = retval->nodesetval; array_init(return_value); - + if (result != NULL) { for (i = 0; i < result->nodeNr; ++i) { nodeptr = result->nodeTab[i]; @@ -1412,9 +1412,15 @@ SXE_METHOD(asXML) if (node) { if (node->parent && (XML_DOCUMENT_NODE == node->parent->type)) { xmlDocDumpMemoryEnc((xmlDocPtr) sxe->document->ptr, &strval, &strval_len, ((xmlDocPtr) sxe->document->ptr)->encoding); - RETVAL_STRINGL((char *)strval, strval_len, 1); + if (!strval) { + RETVAL_FALSE; + } else { + RETVAL_STRINGL((char *)strval, strval_len, 1); + } xmlFree(strval); } else { + char *return_content; + size_t return_len; /* Should we be passing encoding information instead of NULL? */ outbuf = xmlAllocOutputBuffer(NULL); @@ -1425,10 +1431,17 @@ SXE_METHOD(asXML) xmlNodeDumpOutput(outbuf, (xmlDocPtr) sxe->document->ptr, node, 0, 0, ((xmlDocPtr) sxe->document->ptr)->encoding); xmlOutputBufferFlush(outbuf); #ifdef LIBXML2_NEW_BUFFER - RETVAL_STRINGL((char *)xmlOutputBufferGetContent(outbuf), xmlOutputBufferGetSize(outbuf), 1); + return_content = (char *)xmlOutputBufferGetContent(outbuf); + return_len = xmlOutputBufferGetSize(outbuf); #else - RETVAL_STRINGL((char *)outbuf->buffer->content, outbuf->buffer->use, 1); + return_content = (char *)outbuf->buffer->content; + return_len = outbuf->buffer->use; #endif + if (!return_content) { + RETVAL_FALSE; + } else { + RETVAL_STRINGL_CHECK(return_content, return_len, 1); + } xmlOutputBufferClose(outbuf); } } else { @@ -1542,11 +1555,11 @@ SXE_METHOD(getDocNamespaces) }else{ GET_NODE(sxe, node); } - + if (node == NULL) { RETURN_FALSE; } - + array_init(return_value); sxe_add_registered_namespaces(sxe, node, recursive, return_value TSRMLS_CC); } @@ -1933,7 +1946,7 @@ SXE_METHOD(count) } php_sxe_count_elements_helper(sxe, &count TSRMLS_CC); - + RETURN_LONG(count); } /* }}} */ -- 2.1.4