From 7ed4b9485ead4995e576cb2620e0ae27790b211d Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 15 Oct 2016 14:51:59 +0100 Subject: [PATCH 1/3] few realloc calls changes and overflow checks related. --- Zend/zend_alloc.c | 6 ++- ext/opcache/zend_accelerator_blacklist.c | 15 ++++++- ext/xmlrpc/libxmlrpc/base64.c | 12 +++++- ext/xmlrpc/libxmlrpc/encodings.c | 9 ++-- ext/xmlrpc/libxmlrpc/simplestring.c | 10 ++++- main/network.c | 37 +++++++++++++++-- main/php_ini.c | 27 +++++++----- sapi/cgi/cgi_main.c | 39 ++++++++++++++++-- sapi/cli/php_cli.c | 47 +++++++++++++++++---- sapi/phpdbg/phpdbg.c | 52 ++++++++++++++++++++---- 10 files changed, 211 insertions(+), 43 deletions(-) diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index f52ce7985ebe9..746e58853a110 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -2822,10 +2822,12 @@ ZEND_API void * __zend_calloc(size_t nmemb, size_t len) ZEND_API void * __zend_realloc(void *p, size_t len) { - p = realloc(p, len); - if (EXPECTED(p)) { + void *pp = realloc(p, len); + if (EXPECTED(pp)) { + p = pp; return p; } + free(p); zend_out_of_memory(); } diff --git a/ext/opcache/zend_accelerator_blacklist.c b/ext/opcache/zend_accelerator_blacklist.c index db61e1e9d39b6..a52f7c33d394e 100644 --- a/ext/opcache/zend_accelerator_blacklist.c +++ b/ext/opcache/zend_accelerator_blacklist.c @@ -218,8 +218,21 @@ void zend_accel_blacklist_shutdown(zend_blacklist *blacklist) static inline void zend_accel_blacklist_allocate(zend_blacklist *blacklist) { if (blacklist->pos == blacklist->size) { + if ((blacklist->size + ZEND_BLACKLIST_BLOCK_SIZE) >= INT_MAX) { + zend_accel_blacklist_shutdown(blacklist); + zend_accel_error(ACCEL_LOG_FATAL, "Blacklist increase: block size out of range\n"); + return; + } + blacklist->size += ZEND_BLACKLIST_BLOCK_SIZE; - blacklist->entries = (zend_blacklist_entry *) realloc(blacklist->entries, sizeof(zend_blacklist_entry)*blacklist->size); + zend_blacklist_entry * entries = (zend_blacklist_entry *) realloc(blacklist->entries, sizeof(zend_blacklist_entry) * blacklist->size); + if (!entries) { + zend_accel_blacklist_shutdown(blacklist); + zend_accel_error(ACCEL_LOG_FATAL, "Blacklist increase: no memory\n"); + return; + } + + blacklist->entries = entries; } } diff --git a/ext/xmlrpc/libxmlrpc/base64.c b/ext/xmlrpc/libxmlrpc/base64.c index fa6cc32b51e98..3195772ad1f57 100644 --- a/ext/xmlrpc/libxmlrpc/base64.c +++ b/ext/xmlrpc/libxmlrpc/base64.c @@ -15,6 +15,7 @@ static const char rcsid[] = "#(@) $Id$"; /* ENCODE -- Encode binary file into base64. */ #include #include +#include #include "base64.h" @@ -34,8 +35,17 @@ void buffer_add(struct buffer_st *b, char c) *(b->ptr++) = c; b->offset++; if (b->offset == b->length) { + if (b->length + 512 >= INT_MAX) { + buffer_delete(b); + return; + } b->length += 512; - b->data = realloc(b->data, b->length); + char *data = realloc(b->data, b->length); + if (!data) { + buffer_delete(b); + return; + } + b->data = data; b->ptr = b->data + b->offset; } } diff --git a/ext/xmlrpc/libxmlrpc/encodings.c b/ext/xmlrpc/libxmlrpc/encodings.c index 081e38e5deb0b..18ad6a0441c6f 100644 --- a/ext/xmlrpc/libxmlrpc/encodings.c +++ b/ext/xmlrpc/libxmlrpc/encodings.c @@ -45,6 +45,7 @@ static const char rcsid[] = "#(@) $Id$"; #include #include +#include #ifdef HAVE_GICONV_H #include @@ -81,14 +82,16 @@ static char* convert(const char* src, int src_len, int *new_len, const char* fro while(inlenleft) { st = iconv(ic, (char**)&src, &inlenleft, &out_ptr, &outlenleft); if(st == -1) { - if(errno == E2BIG) { + if(errno == E2BIG && (outlen + inlenleft) < INT_MAX) { int diff = out_ptr - outbuf; outlen += inlenleft; outlenleft += inlenleft; - outbuf = (char*)realloc(outbuf, outlen + 1); - if(!outbuf) { + char *poutbuf = (char*)realloc(outbuf, outlen + 1); + if (!poutbuf) { + free(outbuf); break; } + outbuf = poutbuf; out_ptr = outbuf + diff; } else { diff --git a/ext/xmlrpc/libxmlrpc/simplestring.c b/ext/xmlrpc/libxmlrpc/simplestring.c index c88754fb9ae18..19763ce2da07b 100644 --- a/ext/xmlrpc/libxmlrpc/simplestring.c +++ b/ext/xmlrpc/libxmlrpc/simplestring.c @@ -216,9 +216,15 @@ void simplestring_addn(simplestring* target, const char* source, size_t add_len) } if(newsize < (target->len + add_len + 1)) { /* some kind of overflow happened */ - return; + simplestring_free(target); + return; } - target->str = (char*)realloc(target->str, newsize); + char *str = (char*)realloc(target->str, newsize); + if (!str) { + simplestring_free(target); + return; + } + target->str = str; target->size = target->str ? newsize : 0; } diff --git a/main/network.c b/main/network.c index aedff7e2072aa..75d85e4c33cee 100644 --- a/main/network.c +++ b/main/network.c @@ -1277,6 +1277,9 @@ PHPAPI int php_poll2(php_pollfd *ufds, unsigned int nfds, int timeout) } #endif +#define FREETMPBUF() \ + free(*tmphstbuf); \ + *tmphstbuf = 0 #if defined(HAVE_GETHOSTBYNAME_R) #ifdef HAVE_FUNC_GETHOSTBYNAME_R_6 struct hostent * gethostname_re (const char *host,struct hostent *hostbuf,char **tmphstbuf,size_t *hstbuflen) @@ -1293,8 +1296,15 @@ struct hostent * gethostname_re (const char *host,struct hostent *hostbuf,char * gethostbyname_r(host,hostbuf,*tmphstbuf,*hstbuflen,&hp,&herr)) && (errno == ERANGE)) { /* Enlarge the buffer. */ + if (*hstbuflen * 2 >= SIZE_MAX) { + goto fail; + } *hstbuflen *= 2; - *tmphstbuf = (char *)realloc (*tmphstbuf,*hstbuflen); + char *ptmphstbuf = (char *)realloc(*tmphstbuf, *hstbuflen); + if (!ptmphstbuf) { + goto fail; + } + *tmphstbuf = ptmphstbuf; } if (res != SUCCESS) { @@ -1302,6 +1312,10 @@ struct hostent * gethostname_re (const char *host,struct hostent *hostbuf,char * } return hp; +fail: + FREETMPBUF(); + return NULL; + } #endif #ifdef HAVE_FUNC_GETHOSTBYNAME_R_5 @@ -1319,10 +1333,20 @@ struct hostent * gethostname_re (const char *host,struct hostent *hostbuf,char * gethostbyname_r(host,hostbuf,*tmphstbuf,*hstbuflen,&herr))) && (errno == ERANGE)) { /* Enlarge the buffer. */ + if (*hstbuflen * 2 >= SIZE_MAX) { + goto fail; + } *hstbuflen *= 2; - *tmphstbuf = (char *)realloc (*tmphstbuf,*hstbuflen); + char *ptmphstbuf = (char *)realloc(*tmphstbuf, *hstbuflen); + if (!ptmphstbuf) { + goto fail; + } + *tmphstbuf = ptmphstbuf; } return hp; +fail: + FREETMPBUF(); + return NULL; } #endif #ifdef HAVE_FUNC_GETHOSTBYNAME_R_3 @@ -1334,7 +1358,11 @@ struct hostent * gethostname_re (const char *host,struct hostent *hostbuf,char * } else { if (*hstbuflen < sizeof(struct hostent_data)) { *hstbuflen = sizeof(struct hostent_data); - *tmphstbuf = (char *)realloc(*tmphstbuf, *hstbuflen); + char *ptmphstbuf = (char *)realloc(*tmphstbuf, *hstbuflen); + if (!ptmphstbuf) { + goto fail; + } + *tmphstbuf = ptmphstbuf; } } memset((void *)(*tmphstbuf),0,*hstbuflen); @@ -1344,6 +1372,9 @@ struct hostent * gethostname_re (const char *host,struct hostent *hostbuf,char * } return hostbuf; +fail: + FREETMPBUF(); + return NULL; } #endif #endif diff --git a/main/php_ini.c b/main/php_ini.c index d056f51edd6ea..64d0a69e1acca 100644 --- a/main/php_ini.c +++ b/main/php_ini.c @@ -381,7 +381,7 @@ int php_init_config(void) { char *php_ini_file_name = NULL; char *php_ini_search_path = NULL; - int php_ini_scanned_path_len; + size_t php_ini_scanned_path_len; char *open_basedir; int free_ini_search_path = 0; zend_file_handle fh; @@ -403,7 +403,7 @@ int php_init_config(void) php_ini_search_path = sapi_module.php_ini_path_override; free_ini_search_path = 0; } else if (!sapi_module.php_ini_ignore) { - int search_path_size; + size_t search_path_size; char *default_location; char *env_location; static const char paths_separator[] = { ZEND_PATHS_SEPARATOR, 0 }; @@ -450,7 +450,7 @@ int php_init_config(void) * Prepare search path */ - search_path_size = MAXPATHLEN * 4 + (int)strlen(env_location) + 3 + 1; + search_path_size = MAXPATHLEN * 4 + strlen(env_location) + 3 + 1; php_ini_search_path = (char *) emalloc(search_path_size); free_ini_search_path = 1; php_ini_search_path[0] = 0; @@ -611,7 +611,7 @@ int php_init_config(void) /* Or fall back using possible --with-config-file-scan-dir setting (defaults to empty string!) */ php_ini_scanned_path = PHP_CONFIG_FILE_SCAN_DIR; } - php_ini_scanned_path_len = (int)strlen(php_ini_scanned_path); + php_ini_scanned_path_len = strlen(php_ini_scanned_path); /* Scan and parse any .ini files found in scan path if path not empty. */ if (!sapi_module.php_ini_ignore && php_ini_scanned_path_len) { @@ -623,9 +623,9 @@ int php_init_config(void) zend_file_handle fh2; zend_llist scanned_ini_list; zend_llist_element *element; - int l, total_l = 0; + size_t l, total_l = 0; char *bufpath, *debpath, *endpath; - int lenpath; + size_t lenpath; zend_llist_init(&scanned_ini_list, sizeof(char *), (llist_dtor_func_t) free_estring, 1); memset(&fh2, 0, sizeof(fh2)); @@ -641,7 +641,7 @@ int php_init_config(void) to allow "/foo/php.d:" or ":/foo/php.d" */ debpath = PHP_CONFIG_FILE_SCAN_DIR; } - lenpath = (int)strlen(debpath); + lenpath = strlen(debpath); if (lenpath > 0 && (ndir = php_scandir(debpath, &namelist, 0, php_alphasort)) > 0) { @@ -668,7 +668,7 @@ int php_init_config(void) if (zend_parse_ini_file(&fh2, 1, ZEND_INI_SCANNER_NORMAL, (zend_ini_parser_cb_t) php_ini_parser_cb, &configuration_hash) == SUCCESS) { /* Here, add it to the list of ini files read */ - l = (int)strlen(ini_file); + l = strlen(ini_file); total_l += l + 2; p = estrndup(ini_file, l); zend_llist_add_element(&scanned_ini_list, &p); @@ -684,8 +684,15 @@ int php_init_config(void) efree(bufpath); if (total_l) { - int php_ini_scanned_files_len = (php_ini_scanned_files) ? (int)strlen(php_ini_scanned_files) + 1 : 0; - php_ini_scanned_files = (char *) realloc(php_ini_scanned_files, php_ini_scanned_files_len + total_l + 1); + size_t php_ini_scanned_files_len = (php_ini_scanned_files) ? strlen(php_ini_scanned_files) + 1 : 0; + char *php_ini_scanned_files_t = (char *) realloc(php_ini_scanned_files, php_ini_scanned_files_len + total_l + 1); + if (!php_ini_scanned_files_t) { + zend_llist_destroy(&scanned_ini_list); + php_shutdown_config(); + return FAILURE; + } + + php_ini_scanned_files = php_ini_scanned_files_t; if (!php_ini_scanned_files_len) { *php_ini_scanned_files = '\0'; } diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index 0b6deb10e8255..3c12dad59b3e4 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -1860,12 +1860,19 @@ int main(int argc, char *argv[]) case 'd': { /* define ini entries on command line */ size_t len = strlen(php_optarg); - char *val; + char *val, *pini_entries; if ((val = strchr(php_optarg, '='))) { val++; if (!isalnum(*val) && *val != '"' && *val != '\'' && *val != '\0') { - cgi_sapi_module.ini_entries = realloc(cgi_sapi_module.ini_entries, ini_entries_len + len + sizeof("\"\"\n\0")); + if ((ini_entries_len + len + sizeof("\"\"\n\0")) >= SIZE_MAX) { + goto out; + } + pini_entries = realloc(cgi_sapi_module.ini_entries, ini_entries_len + len + sizeof("\"\"\n\0")); + if (!pini_entries) { + goto out; + } + cgi_sapi_module.ini_entries = pini_entries; memcpy(cgi_sapi_module.ini_entries + ini_entries_len, php_optarg, (val - php_optarg)); ini_entries_len += (val - php_optarg); memcpy(cgi_sapi_module.ini_entries + ini_entries_len, "\"", 1); @@ -1875,13 +1882,27 @@ int main(int argc, char *argv[]) memcpy(cgi_sapi_module.ini_entries + ini_entries_len, "\"\n\0", sizeof("\"\n\0")); ini_entries_len += sizeof("\n\0\"") - 2; } else { - cgi_sapi_module.ini_entries = realloc(cgi_sapi_module.ini_entries, ini_entries_len + len + sizeof("\n\0")); + if ((ini_entries_len + len + sizeof("\n\0")) >= SIZE_MAX) { + goto out; + } + pini_entries = realloc(cgi_sapi_module.ini_entries, ini_entries_len + len + sizeof("\n\0")); + if (!pini_entries) { + goto out; + } + cgi_sapi_module.ini_entries = pini_entries; memcpy(cgi_sapi_module.ini_entries + ini_entries_len, php_optarg, len); memcpy(cgi_sapi_module.ini_entries + ini_entries_len + len, "\n\0", sizeof("\n\0")); ini_entries_len += len + sizeof("\n\0") - 2; } } else { - cgi_sapi_module.ini_entries = realloc(cgi_sapi_module.ini_entries, ini_entries_len + len + sizeof("=1\n\0")); + if ((ini_entries_len + len + sizeof("=1\n\0")) >= SIZE_MAX) { + goto out; + } + pini_entries = realloc(cgi_sapi_module.ini_entries, ini_entries_len + len + sizeof("=1\n\0")); + if (!pini_entries) { + goto out; + } + cgi_sapi_module.ini_entries = pini_entries; memcpy(cgi_sapi_module.ini_entries + ini_entries_len, php_optarg, len); memcpy(cgi_sapi_module.ini_entries + ini_entries_len + len, "=1\n\0", sizeof("=1\n\0")); ini_entries_len += len + sizeof("=1\n\0") - 2; @@ -2680,9 +2701,11 @@ consult the installation file that came with this distribution, or visit \n\ if (cgi_sapi_module.php_ini_path_override) { free(cgi_sapi_module.php_ini_path_override); + cgi_sapi_module.php_ini_path_override = NULL; } if (cgi_sapi_module.ini_entries) { free(cgi_sapi_module.ini_entries); + cgi_sapi_module.ini_entries = NULL; } } zend_catch { exit_status = 255; @@ -2711,6 +2734,14 @@ consult the installation file that came with this distribution, or visit \n\ } parent_out: + if (cgi_sapi_module.php_ini_path_override) { + free(cgi_sapi_module.php_ini_path_override); + cgi_sapi_module.php_ini_path_override = NULL; + } + if (cgi_sapi_module.ini_entries) { + free(cgi_sapi_module.ini_entries); + cgi_sapi_module.ini_entries = NULL; + } SG(server_context) = NULL; php_module_shutdown(); diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c index dc92045ae7402..fc58674ae3bc2 100644 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@ -1198,7 +1198,7 @@ int main(int argc, char *argv[]) int php_optind = 1, use_extended_info = 0; char *ini_path_override = NULL; char *ini_entries = NULL; - int ini_entries_len = 0; + size_t ini_entries_len = 0; int ini_ignore = 0; sapi_module_struct *sapi_module = &cli_sapi_module; @@ -1267,29 +1267,50 @@ int main(int argc, char *argv[]) break; case 'd': { /* define ini entries on command line */ - int len = (int)strlen(php_optarg); - char *val; + size_t len = strlen(php_optarg); + char *val, *pini_entries; if ((val = strchr(php_optarg, '='))) { val++; if (!isalnum(*val) && *val != '"' && *val != '\'' && *val != '\0') { - ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("\"\"\n\0")); + if ((ini_entries_len + len + sizeof("\"\"\n\0")) >= SIZE_MAX) { + goto out; + } + pini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("\"\"\n\0")); + if (!pini_entries) { + goto out; + } + ini_entries = pini_entries; memcpy(ini_entries + ini_entries_len, php_optarg, (val - php_optarg)); - ini_entries_len += (int)(val - php_optarg); + ini_entries_len += (val - php_optarg); memcpy(ini_entries + ini_entries_len, "\"", 1); ini_entries_len++; memcpy(ini_entries + ini_entries_len, val, len - (val - php_optarg)); - ini_entries_len += len - (int)(val - php_optarg); + ini_entries_len += len - (val - php_optarg); memcpy(ini_entries + ini_entries_len, "\"\n\0", sizeof("\"\n\0")); ini_entries_len += sizeof("\n\0\"") - 2; } else { - ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("\n\0")); + if ((ini_entries_len + len + sizeof("\n\0")) >= SIZE_MAX) { + goto out; + } + pini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("\n\0")); + if (!pini_entries) { + goto out; + } + ini_entries = pini_entries; memcpy(ini_entries + ini_entries_len, php_optarg, len); memcpy(ini_entries + ini_entries_len + len, "\n\0", sizeof("\n\0")); ini_entries_len += len + sizeof("\n\0") - 2; } } else { - ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("=1\n\0")); + if ((ini_entries_len + len + sizeof("=1\n\0")) >= SIZE_MAX) { + goto out; + } + pini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("=1\n\0")); + if (!pini_entries) { + goto out; + } + ini_entries = pini_entries; memcpy(ini_entries + ini_entries_len, php_optarg, len); memcpy(ini_entries + ini_entries_len + len, "=1\n\0", sizeof("=1\n\0")); ini_entries_len += len + sizeof("=1\n\0") - 2; @@ -1329,7 +1350,15 @@ int main(int argc, char *argv[]) if (sapi_module == &cli_sapi_module) { if (ini_entries) { - ini_entries = realloc(ini_entries, ini_entries_len + sizeof(HARDCODED_INI)); + char *pini_entries; + if ((ini_entries_len + sizeof(HARDCODED_INI)) >= SIZE_MAX) { + goto out; + } + pini_entries = realloc(ini_entries, ini_entries_len + sizeof(HARDCODED_INI)); + if (!pini_entries) { + goto out; + } + ini_entries = pini_entries; memmove(ini_entries + sizeof(HARDCODED_INI) - 2, ini_entries, ini_entries_len + 1); memcpy(ini_entries, HARDCODED_INI, sizeof(HARDCODED_INI) - 2); } else { diff --git a/sapi/phpdbg/phpdbg.c b/sapi/phpdbg/phpdbg.c index 18b490570d231..856db932689bf 100644 --- a/sapi/phpdbg/phpdbg.c +++ b/sapi/phpdbg/phpdbg.c @@ -1357,7 +1357,7 @@ int main(int argc, char **argv) /* {{{ */ sapi_module_struct *phpdbg = &phpdbg_sapi_module; char *sapi_name; char *ini_entries; - int ini_entries_len; + size_t ini_entries_len; char **zend_extensions = NULL; zend_ulong zend_extensions_len = 0L; zend_bool ini_ignore; @@ -1457,13 +1457,20 @@ int main(int argc, char **argv) /* {{{ */ ini_override = strdup(php_optarg); break; case 'd': { - int len = strlen(php_optarg); - char *val; + size_t len = strlen(php_optarg); + char *val, *pini_entries; if ((val = strchr(php_optarg, '='))) { val++; if (!isalnum(*val) && *val != '"' && *val != '\'' && *val != '\0') { - ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("\"\"\n\0")); + if ((ini_entries_len + len + sizeof("\"\"\n\0")) >= SIZE_MAX) { + goto phpdbg_out; + } + pini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("\"\"\n\0")); + if (!pini_entries) { + goto phpdbg_out; + } + ini_entries = pini_entries; memcpy(ini_entries + ini_entries_len, php_optarg, (val - php_optarg)); ini_entries_len += (val - php_optarg); memcpy(ini_entries + ini_entries_len, "\"", 1); @@ -1473,13 +1480,27 @@ int main(int argc, char **argv) /* {{{ */ memcpy(ini_entries + ini_entries_len, "\"\n\0", sizeof("\"\n\0")); ini_entries_len += sizeof("\n\0\"") - 2; } else { - ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("\n\0")); + if ((ini_entries_len + len + sizeof("\n\0")) >= SIZE_MAX) { + goto phpdbg_out; + } + pini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("\n\0")); + if (!pini_entries) { + goto phpdbg_out; + } + ini_entries = pini_entries; memcpy(ini_entries + ini_entries_len, php_optarg, len); memcpy(ini_entries + ini_entries_len + len, "\n\0", sizeof("\n\0")); ini_entries_len += len + sizeof("\n\0") - 2; } } else { - ini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("=1\n\0")); + if ((ini_entries_len + len + sizeof("=1\n\0")) >= SIZE_MAX) { + goto phpdbg_out; + } + pini_entries = realloc(ini_entries, ini_entries_len + len + sizeof("=1\n\0")); + if (!pini_entries) { + goto phpdbg_out; + } + ini_entries = pini_entries; memcpy(ini_entries + ini_entries_len, php_optarg, len); memcpy(ini_entries + ini_entries_len + len, "=1\n\0", sizeof("=1\n\0")); ini_entries_len += len + sizeof("=1\n\0") - 2; @@ -1639,7 +1660,15 @@ int main(int argc, char **argv) /* {{{ */ phpdbg->php_ini_path_override = ini_override; if (ini_entries) { - ini_entries = realloc(ini_entries, ini_entries_len + sizeof(phpdbg_ini_hardcoded)); + char *pini_entries; + if ((ini_entries_len + sizeof(phpdbg_ini_hardcoded)) >= SIZE_MAX) { + goto phpdbg_out; + } + pini_entries = realloc(ini_entries, ini_entries_len + sizeof(phpdbg_ini_hardcoded)); + if (!pini_entries) { + goto phpdbg_out; + } + ini_entries = pini_entries; memmove(ini_entries + sizeof(phpdbg_ini_hardcoded) - 2, ini_entries, ini_entries_len + 1); memcpy(ini_entries, phpdbg_ini_hardcoded, sizeof(phpdbg_ini_hardcoded) - 2); } else { @@ -1653,10 +1682,17 @@ int main(int argc, char **argv) /* {{{ */ while (zend_extension < zend_extensions_len) { const char *ze = zend_extensions[zend_extension]; + char *pini_entries; size_t ze_len = strlen(ze); + if ((ze_len + sizeof("zend_extension=\n")) >= SIZE_MAX) { + goto phpdbg_out; + } - ini_entries = realloc( + pini_entries = realloc( ini_entries, ini_entries_len + (ze_len + (sizeof("zend_extension=\n")))); + if (!pini_entries) { + goto phpdbg_out; + } memcpy(&ini_entries[ini_entries_len], "zend_extension=", (sizeof("zend_extension=\n")-1)); ini_entries_len += (sizeof("zend_extension=")-1); memcpy(&ini_entries[ini_entries_len], ze, ze_len); From 92f301bc411ff040f5d78d5b1057bb7e96d7c2e0 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 15 Oct 2016 18:21:13 +0100 Subject: [PATCH 2/3] declare variables beginning of blocks --- ext/opcache/zend_accelerator_blacklist.c | 3 ++- ext/xmlrpc/libxmlrpc/base64.c | 3 ++- ext/xmlrpc/libxmlrpc/simplestring.c | 3 ++- main/network.c | 9 ++++++--- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/ext/opcache/zend_accelerator_blacklist.c b/ext/opcache/zend_accelerator_blacklist.c index a52f7c33d394e..cce745d5569af 100644 --- a/ext/opcache/zend_accelerator_blacklist.c +++ b/ext/opcache/zend_accelerator_blacklist.c @@ -218,6 +218,7 @@ void zend_accel_blacklist_shutdown(zend_blacklist *blacklist) static inline void zend_accel_blacklist_allocate(zend_blacklist *blacklist) { if (blacklist->pos == blacklist->size) { + zend_blacklist_entry *entries; if ((blacklist->size + ZEND_BLACKLIST_BLOCK_SIZE) >= INT_MAX) { zend_accel_blacklist_shutdown(blacklist); zend_accel_error(ACCEL_LOG_FATAL, "Blacklist increase: block size out of range\n"); @@ -225,7 +226,7 @@ static inline void zend_accel_blacklist_allocate(zend_blacklist *blacklist) } blacklist->size += ZEND_BLACKLIST_BLOCK_SIZE; - zend_blacklist_entry * entries = (zend_blacklist_entry *) realloc(blacklist->entries, sizeof(zend_blacklist_entry) * blacklist->size); + entries = (zend_blacklist_entry *) realloc(blacklist->entries, sizeof(zend_blacklist_entry) * blacklist->size); if (!entries) { zend_accel_blacklist_shutdown(blacklist); zend_accel_error(ACCEL_LOG_FATAL, "Blacklist increase: no memory\n"); diff --git a/ext/xmlrpc/libxmlrpc/base64.c b/ext/xmlrpc/libxmlrpc/base64.c index 3195772ad1f57..66da425b2bbe7 100644 --- a/ext/xmlrpc/libxmlrpc/base64.c +++ b/ext/xmlrpc/libxmlrpc/base64.c @@ -35,12 +35,13 @@ void buffer_add(struct buffer_st *b, char c) *(b->ptr++) = c; b->offset++; if (b->offset == b->length) { + char *data; if (b->length + 512 >= INT_MAX) { buffer_delete(b); return; } b->length += 512; - char *data = realloc(b->data, b->length); + data = realloc(b->data, b->length); if (!data) { buffer_delete(b); return; diff --git a/ext/xmlrpc/libxmlrpc/simplestring.c b/ext/xmlrpc/libxmlrpc/simplestring.c index 19763ce2da07b..71909b2601b9e 100644 --- a/ext/xmlrpc/libxmlrpc/simplestring.c +++ b/ext/xmlrpc/libxmlrpc/simplestring.c @@ -206,6 +206,7 @@ void simplestring_addn(simplestring* target, const char* source, size_t add_len) } if(target->len + add_len + 1 > target->size) { + char *str; /* newsize is current length + new length */ newsize = target->len + add_len + 1; incr = target->size * 2; @@ -219,7 +220,7 @@ void simplestring_addn(simplestring* target, const char* source, size_t add_len) simplestring_free(target); return; } - char *str = (char*)realloc(target->str, newsize); + str = (char*)realloc(target->str, newsize); if (!str) { simplestring_free(target); return; diff --git a/main/network.c b/main/network.c index 75d85e4c33cee..8fcaea6bc2dbc 100644 --- a/main/network.c +++ b/main/network.c @@ -1295,12 +1295,13 @@ struct hostent * gethostname_re (const char *host,struct hostent *hostbuf,char * while (( res = gethostbyname_r(host,hostbuf,*tmphstbuf,*hstbuflen,&hp,&herr)) && (errno == ERANGE)) { + char *ptmphstbuf; /* Enlarge the buffer. */ if (*hstbuflen * 2 >= SIZE_MAX) { goto fail; } *hstbuflen *= 2; - char *ptmphstbuf = (char *)realloc(*tmphstbuf, *hstbuflen); + ptmphstbuf = (char *)realloc(*tmphstbuf, *hstbuflen); if (!ptmphstbuf) { goto fail; } @@ -1332,12 +1333,13 @@ struct hostent * gethostname_re (const char *host,struct hostent *hostbuf,char * while ((NULL == ( hp = gethostbyname_r(host,hostbuf,*tmphstbuf,*hstbuflen,&herr))) && (errno == ERANGE)) { + char *ptmphstbuf; /* Enlarge the buffer. */ if (*hstbuflen * 2 >= SIZE_MAX) { goto fail; } *hstbuflen *= 2; - char *ptmphstbuf = (char *)realloc(*tmphstbuf, *hstbuflen); + ptmphstbuf = (char *)realloc(*tmphstbuf, *hstbuflen); if (!ptmphstbuf) { goto fail; } @@ -1357,8 +1359,9 @@ struct hostent * gethostname_re (const char *host,struct hostent *hostbuf,char * *tmphstbuf = (char *)malloc (*hstbuflen); } else { if (*hstbuflen < sizeof(struct hostent_data)) { + char *ptmphstbuf; *hstbuflen = sizeof(struct hostent_data); - char *ptmphstbuf = (char *)realloc(*tmphstbuf, *hstbuflen); + ptmphstbuf = (char *)realloc(*tmphstbuf, *hstbuflen); if (!ptmphstbuf) { goto fail; } From 67d15a128170fee2c3deb239895c712958aee99e Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 15 Oct 2016 18:59:53 +0100 Subject: [PATCH 3/3] lowering overflow threshold --- main/network.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main/network.c b/main/network.c index 8fcaea6bc2dbc..adcc8a42b8af2 100644 --- a/main/network.c +++ b/main/network.c @@ -1297,7 +1297,7 @@ struct hostent * gethostname_re (const char *host,struct hostent *hostbuf,char * && (errno == ERANGE)) { char *ptmphstbuf; /* Enlarge the buffer. */ - if (*hstbuflen * 2 >= SIZE_MAX) { + if (*hstbuflen > SIZE_MAX / 2) { goto fail; } *hstbuflen *= 2; @@ -1335,7 +1335,7 @@ struct hostent * gethostname_re (const char *host,struct hostent *hostbuf,char * && (errno == ERANGE)) { char *ptmphstbuf; /* Enlarge the buffer. */ - if (*hstbuflen * 2 >= SIZE_MAX) { + if (*hstbuflen > SIZE_MAX / 2) { goto fail; } *hstbuflen *= 2;