diff --git a/Zend/tests/bug77494.phpt b/Zend/tests/bug77494.phpt deleted file mode 100644 index 7f808c2c0f52a..0000000000000 --- a/Zend/tests/bug77494.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---TEST-- -Bug #77494 (Disabling class causes segfault on member access) ---EXTENSIONS-- -curl ---INI-- -disable_classes=CURLFile,ErrorException ---FILE-- -name); -$b = new ErrorException(); -var_dump($b->message); -?> ---EXPECTF-- -Warning: CURLFile() has been disabled for security reasons in %sbug77494.php on line 2 - -Warning: Undefined property: CURLFile::$name in %s on line %d -NULL - -Warning: ErrorException() has been disabled for security reasons in %s on line %d - -Warning: Undefined property: ErrorException::$message in %s on line %d -NULL diff --git a/Zend/tests/disable_classes_warning.phpt b/Zend/tests/disable_classes_warning.phpt new file mode 100644 index 0000000000000..c3692bf52972f --- /dev/null +++ b/Zend/tests/disable_classes_warning.phpt @@ -0,0 +1,27 @@ +--TEST-- +Check that warning is emitted when disabling classes +--INI-- +disable_classes=Exception +--FILE-- + +--EXPECTF-- +object(Exception)#1 (7) { + ["message":protected]=> + string(0) "" + ["string":"Exception":private]=> + string(0) "" + ["code":protected]=> + int(0) + ["file":protected]=> + string(%d) "%s" + ["line":protected]=> + int(2) + ["trace":"Exception":private]=> + array(0) { + } + ["previous":"Exception":private]=> + NULL +} diff --git a/Zend/tests/errmsg_021.phpt b/Zend/tests/errmsg_021.phpt deleted file mode 100644 index 7514e68359044..0000000000000 --- a/Zend/tests/errmsg_021.phpt +++ /dev/null @@ -1,17 +0,0 @@ ---TEST-- -errmsg: disabled class ---INI-- -disable_classes=stdclass ---FILE-- - ---EXPECTF-- -Warning: test() has been disabled for security reasons in %s on line %d -Done diff --git a/Zend/zend_API.c b/Zend/zend_API.c index ae7a06f011761..c7d5cde2443e4 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -3579,77 +3579,6 @@ ZEND_API void zend_disable_functions(const char *function_list) /* {{{ */ } /* }}} */ -#ifdef ZEND_WIN32 -#pragma optimize("", off) -#endif -static ZEND_COLD zend_object *display_disabled_class(zend_class_entry *class_type) /* {{{ */ -{ - zend_object *intern; - - intern = zend_objects_new(class_type); - - /* Initialize default properties */ - if (EXPECTED(class_type->default_properties_count != 0)) { - zval *p = intern->properties_table; - zval *end = p + class_type->default_properties_count; - do { - ZVAL_UNDEF(p); - p++; - } while (p != end); - } - - zend_error(E_WARNING, "%s() has been disabled for security reasons", ZSTR_VAL(class_type->name)); - return intern; -} -#ifdef ZEND_WIN32 -#pragma optimize("", on) -#endif -/* }}} */ - -static const zend_function_entry disabled_class_new[] = { - ZEND_FE_END -}; - -ZEND_API zend_result zend_disable_class(const char *class_name, size_t class_name_length) /* {{{ */ -{ - zend_class_entry *disabled_class; - zend_string *key; - zend_function *fn; - zend_property_info *prop; - - key = zend_string_alloc(class_name_length, 0); - zend_str_tolower_copy(ZSTR_VAL(key), class_name, class_name_length); - disabled_class = zend_hash_find_ptr(CG(class_table), key); - zend_string_release_ex(key, 0); - if (!disabled_class) { - return FAILURE; - } - - /* Will be reset by INIT_CLASS_ENTRY. */ - free(disabled_class->interfaces); - - INIT_CLASS_ENTRY_INIT_METHODS((*disabled_class), disabled_class_new); - disabled_class->create_object = display_disabled_class; - - ZEND_HASH_MAP_FOREACH_PTR(&disabled_class->function_table, fn) { - if ((fn->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS)) && - fn->common.scope == disabled_class) { - zend_free_internal_arg_info(&fn->internal_function); - } - } ZEND_HASH_FOREACH_END(); - zend_hash_clean(&disabled_class->function_table); - ZEND_HASH_MAP_FOREACH_PTR(&disabled_class->properties_info, prop) { - if (prop->ce == disabled_class) { - zend_string_release(prop->name); - zend_type_release(prop->type, /* persistent */ 1); - free(prop); - } - } ZEND_HASH_FOREACH_END(); - zend_hash_clean(&disabled_class->properties_info); - return SUCCESS; -} -/* }}} */ - static zend_always_inline zend_class_entry *get_scope(zend_execute_data *frame) { return frame && frame->func ? frame->func->common.scope : NULL; diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 90556fcde4245..697218bc3d805 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -402,7 +402,6 @@ static zend_always_inline zend_result zend_register_class_alias(const char *name zend_register_class_alias_ex(ZEND_NS_NAME(ns, name), sizeof(ZEND_NS_NAME(ns, name))-1, ce, 1) ZEND_API void zend_disable_functions(const char *function_list); -ZEND_API zend_result zend_disable_class(const char *class_name, size_t class_name_length); ZEND_API ZEND_COLD void zend_wrong_param_count(void); ZEND_API ZEND_COLD void zend_wrong_property_read(zval *object, zval *property); diff --git a/main/main.c b/main/main.c index eae9977303333..111c28bddbb87 100644 --- a/main/main.c +++ b/main/main.c @@ -319,41 +319,6 @@ static PHP_INI_MH(OnSetLogFilter) } /* }}} */ -/* {{{ php_disable_classes */ -static void php_disable_classes(void) -{ - char *s = NULL, *e; - - if (!*(INI_STR("disable_classes"))) { - return; - } - - e = PG(disable_classes) = strdup(INI_STR("disable_classes")); - - while (*e) { - switch (*e) { - case ' ': - case ',': - if (s) { - *e = '\0'; - zend_disable_class(s, e-s); - s = NULL; - } - break; - default: - if (!s) { - s = e; - } - break; - } - e++; - } - if (s) { - zend_disable_class(s, e-s); - } -} -/* }}} */ - /* {{{ php_binary_init */ static void php_binary_init(void) { @@ -660,6 +625,17 @@ static PHP_INI_MH(OnChangeMailForceExtra) } /* }}} */ +/* Emit warning when using this INI setting as it is removed */ +static PHP_INI_MH(OnChangeDisableClasses) +{ + if (stage != PHP_INI_SYSTEM) { + return FAILURE; + } + php_error_docref("disable_classes", E_WARNING, "The disable_classes INI setting has been removed and has no effect"); + + return FAILURE; +} + /* defined in browscap.c */ PHP_INI_MH(OnChangeBrowscap); @@ -757,7 +733,7 @@ PHP_INI_BEGIN() PHP_INI_ENTRY("sendmail_path", DEFAULT_SENDMAIL_PATH, PHP_INI_SYSTEM, NULL) PHP_INI_ENTRY("mail.force_extra_parameters",NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnChangeMailForceExtra) PHP_INI_ENTRY("disable_functions", "", PHP_INI_SYSTEM, NULL) - PHP_INI_ENTRY("disable_classes", "", PHP_INI_SYSTEM, NULL) + PHP_INI_ENTRY("disable_classes", "", PHP_INI_SYSTEM, OnChangeDisableClasses) PHP_INI_ENTRY("max_file_uploads", "20", PHP_INI_SYSTEM|PHP_INI_PERDIR, NULL) PHP_INI_ENTRY("max_multipart_body_parts", "-1", PHP_INI_SYSTEM|PHP_INI_PERDIR, NULL) @@ -1975,9 +1951,6 @@ static void core_globals_dtor(php_core_globals *core_globals) ZEND_ASSERT(!core_globals->last_error_message); ZEND_ASSERT(!core_globals->last_error_file); - if (core_globals->disable_classes) { - free(core_globals->disable_classes); - } if (core_globals->php_binary) { free(core_globals->php_binary); } @@ -2235,9 +2208,8 @@ zend_result php_module_startup(sapi_module_struct *sf, zend_module_entry *additi } } - /* disable certain classes and functions as requested by php.ini */ + /* disable certain functions as requested by php.ini */ zend_disable_functions(INI_STR("disable_functions")); - php_disable_classes(); /* make core report what it should */ if ((module = zend_hash_str_find_ptr(&module_registry, "core", sizeof("core")-1)) != NULL) { diff --git a/main/php_globals.h b/main/php_globals.h index b2f2696c2db2c..bd2bd67e753e7 100644 --- a/main/php_globals.h +++ b/main/php_globals.h @@ -142,7 +142,6 @@ struct _php_core_globals { char *php_sys_temp_dir; - char *disable_classes; zend_long max_input_nesting_level; zend_long max_input_vars; diff --git a/main/php_version.h b/main/php_version.h index 1cbfc9afcada9..4d24349b3e7d6 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -1,8 +1,8 @@ /* automatically generated by configure */ /* edit configure.ac to change version number */ #define PHP_MAJOR_VERSION 8 -#define PHP_MINOR_VERSION 4 +#define PHP_MINOR_VERSION 3 #define PHP_RELEASE_VERSION 0 #define PHP_EXTRA_VERSION "-dev" -#define PHP_VERSION "8.4.0-dev" -#define PHP_VERSION_ID 80400 +#define PHP_VERSION "8.3.0-dev" +#define PHP_VERSION_ID 80300 diff --git a/php.ini-development b/php.ini-development index 2ce934f811932..099b2f8d91423 100644 --- a/php.ini-development +++ b/php.ini-development @@ -332,11 +332,6 @@ serialize_precision = -1 ; https://php.net/disable-functions disable_functions = -; This directive allows you to disable certain classes. -; It receives a comma-delimited list of class names. -; https://php.net/disable-classes -disable_classes = - ; Colors for Syntax Highlighting mode. Anything that's acceptable in ; would work. ; https://php.net/syntax-highlighting diff --git a/php.ini-production b/php.ini-production index 43d24fc372087..3108d18b8fa3f 100644 --- a/php.ini-production +++ b/php.ini-production @@ -332,11 +332,6 @@ serialize_precision = -1 ; https://php.net/disable-functions disable_functions = -; This directive allows you to disable certain classes. -; It receives a comma-delimited list of class names. -; https://php.net/disable-classes -disable_classes = - ; Colors for Syntax Highlighting mode. Anything that's acceptable in ; would work. ; https://php.net/syntax-highlighting diff --git a/sapi/fpm/fpm/fpm_php.c b/sapi/fpm/fpm/fpm_php.c index b88c47671a1ec..41f49f96a06ba 100644 --- a/sapi/fpm/fpm/fpm_php.c +++ b/sapi/fpm/fpm/fpm_php.c @@ -48,35 +48,6 @@ static int fpm_php_zend_ini_alter_master(char *name, int name_length, char *new_ } /* }}} */ -static void fpm_php_disable(char *value, int (*zend_disable)(const char *, size_t)) /* {{{ */ -{ - char *s = 0, *e = value; - - while (*e) { - switch (*e) { - case ' ': - case ',': - if (s) { - *e = '\0'; - zend_disable(s, e - s); - s = 0; - } - break; - default: - if (!s) { - s = e; - } - break; - } - e++; - } - - if (s) { - zend_disable(s, e - s); - } -} -/* }}} */ - #define FPM_PHP_INI_ALTERING_ERROR -1 #define FPM_PHP_INI_APPLIED 1 #define FPM_PHP_INI_EXTENSION_FAILED 0 @@ -107,13 +78,6 @@ int fpm_php_apply_defines_ex(struct key_value_s *kv, int mode) /* {{{ */ return FPM_PHP_INI_APPLIED; } - if (!strcmp(name, "disable_classes") && *value) { - char *v = strdup(value); - PG(disable_classes) = v; - fpm_php_disable(v, zend_disable_class); - return FPM_PHP_INI_APPLIED; - } - return FPM_PHP_INI_APPLIED; } /* }}} */ diff --git a/sapi/fpm/www.conf.in b/sapi/fpm/www.conf.in index ff47b50422c2f..14d3e1d48d711 100644 --- a/sapi/fpm/www.conf.in +++ b/sapi/fpm/www.conf.in @@ -474,9 +474,8 @@ pm.max_spare_servers = 3 ; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no. ; Defining 'extension' will load the corresponding shared extension from -; extension_dir. Defining 'disable_functions' or 'disable_classes' will not -; overwrite previously defined php.ini values, but will append the new value -; instead. +; extension_dir. Defining 'disable_functions' will not overwrite previously +; defined php.ini values, but will append the new value instead. ; Note: path INI options can be relative and will be expanded with the prefix ; (pool, global or @prefix@) diff --git a/sapi/fuzzer/fuzzer-json.c b/sapi/fuzzer/fuzzer-json.c index 4335598bc3caa..8a8003aa50415 100644 --- a/sapi/fuzzer/fuzzer-json.c +++ b/sapi/fuzzer/fuzzer-json.c @@ -20,6 +20,7 @@ #include "fuzzer.h" #include "Zend/zend.h" +#include "main/php.h" #include "main/php_config.h" #include "main/php_main.h" diff --git a/sapi/fuzzer/fuzzer-sapi.c b/sapi/fuzzer/fuzzer-sapi.c index baf77ae0463b3..b052f174005b6 100644 --- a/sapi/fuzzer/fuzzer-sapi.c +++ b/sapi/fuzzer/fuzzer-sapi.c @@ -56,8 +56,6 @@ static const char HARDCODED_INI[] = ",crypt" /* openlog() has a known memory-management issue. */ ",openlog" - /* Can cause long loops that bypass the executor step limit. */ - "\ndisable_classes=InfiniteIterator" ; static int startup(sapi_module_struct *sapi_module) @@ -128,6 +126,21 @@ static sapi_module_struct fuzzer_module = { STANDARD_SAPI_MODULE_PROPERTIES }; +static ZEND_COLD zend_object *disable_class_create_handler(zend_class_entry *class_type) /* {{{ */ +{ + zend_throw_error(NULL, "Cannot construct class %s, as it is disabled", ZSTR_VAL(class_type->name)); + return NULL; +} + +static void fuzzer_disable_classes(void) +{ + /* Overwrite built-in constructor for InfiniteIterator as it + * can cause long loops that bypass the executor step limit. */ + /* Lowercase as this is how the CE as stored */ + zend_class_entry *InfiniteIterator_class = zend_hash_str_find(CG(class_table), "infiniteiterator", strlen("infiniteiterator")); + InfiniteIterator_class->create_object = disable_class_create_handler; +} + int fuzzer_init_php(const char *extra_ini) { #ifdef __SANITIZE_ADDRESS__ @@ -183,6 +196,8 @@ int fuzzer_request_startup(void) SIGG(check) = 0; #endif + fuzzer_disable_classes(); + return SUCCESS; } diff --git a/sapi/fuzzer/fuzzer-unserialize.c b/sapi/fuzzer/fuzzer-unserialize.c index ff26e5b1e8da3..0e1f83bb6b694 100644 --- a/sapi/fuzzer/fuzzer-unserialize.c +++ b/sapi/fuzzer/fuzzer-unserialize.c @@ -18,6 +18,7 @@ #include "fuzzer.h" #include "Zend/zend.h" +#include "main/php.h" #include "main/php_config.h" #include "main/php_main.h" diff --git a/sapi/fuzzer/fuzzer-unserializehash.c b/sapi/fuzzer/fuzzer-unserializehash.c index 5d29eb5fb8c61..89326d3c7b50b 100644 --- a/sapi/fuzzer/fuzzer-unserializehash.c +++ b/sapi/fuzzer/fuzzer-unserializehash.c @@ -16,6 +16,7 @@ #include "fuzzer.h" #include "Zend/zend.h" +#include "main/php.h" #include "main/php_config.h" #include "main/php_main.h"