From 078f3abb05fac4492f2ccd243cd4581da1ddcca0 Mon Sep 17 00:00:00 2001 From: foobar Date: Thu, 21 Apr 2005 14:47:13 +0000 Subject: [PATCH] MFH: - Fixed bug #32647 (Using register_shutdown_function() with invalid callback can crash PHP) --- NEWS | 2 ++ ext/standard/basic_functions.c | 56 ++++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/NEWS b/NEWS index 3d140c3243..21d67e44ef 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,8 @@ PHP 4 NEWS (Derick) - Fixed bug #32682 (ext/mssql: Error on module shutdown when called from activescript). (Frank) +- Fixed bug #32647 (Using register_shutdown_function() with invalid callback + can crash PHP). (Jani) - Fixed bug #32591 (ext/mysql: Unsatisfied symbol: ntohs with HP-UX). (Jani) - Fixed bug #32589 (Possible crash inside imap_mail_compose, with charsets). (Ilia) diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 8904dbdc6b..7ef15f34e4 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -2089,17 +2089,21 @@ void user_tick_function_dtor(user_tick_function_entry *tick_function_entry) static int user_shutdown_function_call(php_shutdown_function_entry *shutdown_function_entry TSRMLS_DC) { zval retval; - - if (call_user_function( EG(function_table), NULL, - shutdown_function_entry->arguments[0], - &retval, - shutdown_function_entry->arg_count - 1, - shutdown_function_entry->arguments + 1 - TSRMLS_CC ) == SUCCESS ) { + char *function_name = NULL; + + if (!zend_is_callable(shutdown_function_entry->arguments[0], 0, &function_name)) { + php_error(E_WARNING, "(Registered shutdown functions) Unable to call %s() - function does not exist", function_name); + } else if (call_user_function(EG(function_table), NULL, + shutdown_function_entry->arguments[0], + &retval, + shutdown_function_entry->arg_count - 1, + shutdown_function_entry->arguments + 1 + TSRMLS_CC ) == SUCCESS) + { zval_dtor(&retval); - - } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to call %s() - function does not exist", Z_STRVAL_P(shutdown_function_entry->arguments[0])); + } + if (function_name) { + efree(function_name); } return 0; } @@ -2192,6 +2196,7 @@ void php_free_shutdown_functions(TSRMLS_D) PHP_FUNCTION(register_shutdown_function) { php_shutdown_function_entry shutdown_function_entry; + char *function_name = NULL; int i; shutdown_function_entry.arg_count = ZEND_NUM_ARGS(); @@ -2200,26 +2205,31 @@ PHP_FUNCTION(register_shutdown_function) WRONG_PARAM_COUNT; } - shutdown_function_entry.arguments = (pval **) safe_emalloc(sizeof(pval *), shutdown_function_entry.arg_count, 0); + shutdown_function_entry.arguments = (zval **) safe_emalloc(sizeof(zval *), shutdown_function_entry.arg_count, 0); if (zend_get_parameters_array(ht, shutdown_function_entry.arg_count, shutdown_function_entry.arguments) == FAILURE) { RETURN_FALSE; } - /* Prevent entering of anything but arrays/strings */ - if (Z_TYPE_P(shutdown_function_entry.arguments[0]) != IS_ARRAY) { - convert_to_string(shutdown_function_entry.arguments[0]); - } - - if (!BG(user_shutdown_function_names)) { - ALLOC_HASHTABLE(BG(user_shutdown_function_names)); - zend_hash_init(BG(user_shutdown_function_names), 0, NULL, (void (*)(void *)) user_shutdown_function_dtor, 0); - } + /* Prevent entering of anything but valid callback (syntax check only!) */ + if (!zend_is_callable(shutdown_function_entry.arguments[0], 1, &function_name)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid shutdown callback '%s' passed", function_name); + efree(shutdown_function_entry.arguments); + RETVAL_FALSE; + } else { + if (!BG(user_shutdown_function_names)) { + ALLOC_HASHTABLE(BG(user_shutdown_function_names)); + zend_hash_init(BG(user_shutdown_function_names), 0, NULL, (void (*)(void *)) user_shutdown_function_dtor, 0); + } - for (i = 0; i < shutdown_function_entry.arg_count; i++) { - shutdown_function_entry.arguments[i]->refcount++; + for (i = 0; i < shutdown_function_entry.arg_count; i++) { + shutdown_function_entry.arguments[i]->refcount++; + } + zend_hash_next_index_insert(BG(user_shutdown_function_names), &shutdown_function_entry, sizeof(php_shutdown_function_entry), NULL); + } + if (function_name) { + efree(function_name); } - zend_hash_next_index_insert(BG(user_shutdown_function_names), &shutdown_function_entry, sizeof(php_shutdown_function_entry), NULL); } /* }}} */ -- 2.50.1