diff --git a/Zend/zend_API.c b/Zend/zend_API.c index e72043ead5870..e90f877f9848e 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -5301,3 +5301,15 @@ ZEND_API zend_result zend_get_default_from_internal_arg_info( #endif return get_default_via_ast(default_value_zval, ZSTR_VAL(default_value)); } + +ZEND_API bool zend_validate_file_permissions(zend_long mode, uint32_t arg_num +) { + if (mode < 0 || (mode & ~07777)) { + zend_argument_value_error( + arg_num, + "must be between 0 and 0o7777" + ); + return false; + } + return true; +} diff --git a/Zend/zend_API.h b/Zend/zend_API.h index d78ee6604e34d..2dbb5742ac2d5 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -2585,6 +2585,8 @@ static zend_always_inline bool zend_parse_arg_obj_or_str( return zend_parse_arg_str(arg, destination_string, allow_null, arg_num); } +ZEND_API bool zend_validate_file_permissions(zend_long mode, uint32_t arg_num); + END_EXTERN_C() #endif /* ZEND_API_H */ diff --git a/ext/standard/file.c b/ext/standard/file.c index a7b73f1fe56eb..ea3e59685b453 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -1087,6 +1087,10 @@ PHP_FUNCTION(mkdir) Z_PARAM_RESOURCE_OR_NULL(zcontext) ZEND_PARSE_PARAMETERS_END(); + if (!zend_validate_file_permissions(mode, 2)) { + RETURN_THROWS(); + } + context = php_stream_context_from_zval(zcontext, 0); RETURN_BOOL(php_stream_mkdir(dir, (int)mode, (recursive ? PHP_STREAM_MKDIR_RECURSIVE : 0) | REPORT_ERRORS, context)); diff --git a/ext/standard/tests/file/mkdir_invalid_mode.phpt b/ext/standard/tests/file/mkdir_invalid_mode.phpt new file mode 100644 index 0000000000000..c36a8f6c4b846 --- /dev/null +++ b/ext/standard/tests/file/mkdir_invalid_mode.phpt @@ -0,0 +1,34 @@ +--TEST-- +mkdir(): invalid mode +--FILE-- +getMessage(), PHP_EOL; + } catch (Exception $e) { + echo "Other exception: ", $e->getMessage(), PHP_EOL; + } +} +?> +--EXPECT-- +Testing mode: 1000000 +mkdir(): Argument #2 ($permissions) must be between 0 and 0o7777 +Testing mode: -1 +mkdir(): Argument #2 ($permissions) must be between 0 and 0o7777 +Testing mode: 4096 +mkdir(): Argument #2 ($permissions) must be between 0 and 0o7777 +Testing mode: 131071 +mkdir(): Argument #2 ($permissions) must be between 0 and 0o7777 +Testing mode: 12345 +mkdir(): Argument #2 ($permissions) must be between 0 and 0o7777