diff --git a/ext/opcache/ZendAccelerator.h b/ext/opcache/ZendAccelerator.h index 91642e288d31..df7a41b1e8ad 100644 --- a/ext/opcache/ZendAccelerator.h +++ b/ext/opcache/ZendAccelerator.h @@ -176,6 +176,7 @@ typedef struct _zend_accel_directives { char *lockfile_path; #endif char *file_cache; + mode_t file_cache_permissions; bool file_cache_read_only; bool file_cache_only; bool file_cache_consistency_checks; diff --git a/ext/opcache/tests/file_cache_permissions.phpt b/ext/opcache/tests/file_cache_permissions.phpt new file mode 100644 index 000000000000..c8d6c7fda896 --- /dev/null +++ b/ext/opcache/tests/file_cache_permissions.phpt @@ -0,0 +1,70 @@ +--TEST-- +opcache.file_cache_permissions +--EXTENSIONS-- +opcache +--SKIPIF-- + +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_cache="{PWD}/opcache" +opcache.file_cache_only=1 +opcache.file_update_protection=0 +opcache.file_cache_permissions=0644 +--FILE-- +isFile()) { + continue; + } + if (str_ends_with($splFileInfo->getPathname(), '/foo.php.bin')) { + var_dump(sprintf('%o', substr(fileperms($splFileInfo->getPathname()), -3))); + break; + } +} +?> +--CLEAN-- +getRealPath(); + if ($splFileInfo->isDir()) { + @rmdir($path); + } else { + @unlink($path); + } + } + @rmdir($opcacheDirectory); +} +?> +--EXPECT-- +string(6) "644" diff --git a/ext/opcache/zend_accelerator_module.c b/ext/opcache/zend_accelerator_module.c index 465b15cd9576..52a22fa38a53 100644 --- a/ext/opcache/zend_accelerator_module.c +++ b/ext/opcache/zend_accelerator_module.c @@ -18,6 +18,7 @@ */ #include +#include #include "php.h" #include "ZendAccelerator.h" @@ -193,6 +194,23 @@ static ZEND_INI_MH(OnUpdateFileCache) return SUCCESS; } +static ZEND_INI_MH(OnUpdateFileCachePermissions) +{ + mode_t *p = ZEND_INI_GET_ADDR(); + char *end; + unsigned long val; + + errno = 0; + val = ZEND_STRTOL(ZSTR_VAL(new_value), &end, 8); + if (errno != 0 || end != ZSTR_VAL(new_value) + ZSTR_LEN(new_value) || val > 0777) { + zend_accel_error(ACCEL_LOG_WARNING, "opcache.file_cache_permissions must be a valid octal mode between 0000 and 0777.\n"); + return FAILURE; + } + + *p = (mode_t) val; + return SUCCESS; +} + #ifdef HAVE_JIT static ZEND_INI_MH(OnUpdateJit) { @@ -320,6 +338,7 @@ ZEND_INI_BEGIN() #endif STD_PHP_INI_ENTRY("opcache.file_cache" , NULL , PHP_INI_SYSTEM, OnUpdateFileCache, accel_directives.file_cache, zend_accel_globals, accel_globals) + STD_PHP_INI_ENTRY("opcache.file_cache_permissions", "0600", PHP_INI_SYSTEM, OnUpdateFileCachePermissions, accel_directives.file_cache_permissions, zend_accel_globals, accel_globals) STD_PHP_INI_BOOLEAN("opcache.file_cache_read_only" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_cache_read_only, zend_accel_globals, accel_globals) STD_PHP_INI_BOOLEAN("opcache.file_cache_only" , "0" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_cache_only, zend_accel_globals, accel_globals) STD_PHP_INI_BOOLEAN("opcache.file_cache_consistency_checks" , "1" , PHP_INI_SYSTEM, OnUpdateBool, accel_directives.file_cache_consistency_checks, zend_accel_globals, accel_globals) @@ -845,6 +864,7 @@ ZEND_FUNCTION(opcache_get_configuration) #endif add_assoc_string(&directives, "opcache.file_cache", ZCG(accel_directives).file_cache ? ZCG(accel_directives).file_cache : ""); + add_assoc_long(&directives, "opcache.file_cache_permissions", ZCG(accel_directives).file_cache_permissions); add_assoc_bool(&directives, "opcache.file_cache_read_only", ZCG(accel_directives).file_cache_read_only); add_assoc_bool(&directives, "opcache.file_cache_only", ZCG(accel_directives).file_cache_only); add_assoc_bool(&directives, "opcache.file_cache_consistency_checks", ZCG(accel_directives).file_cache_consistency_checks); diff --git a/ext/opcache/zend_file_cache.c b/ext/opcache/zend_file_cache.c index af59b9b2c34a..412cbc3c817f 100644 --- a/ext/opcache/zend_file_cache.c +++ b/ext/opcache/zend_file_cache.c @@ -1171,7 +1171,7 @@ int zend_file_cache_script_store(zend_persistent_script *script, bool in_shm) return FAILURE; } - fd = zend_file_cache_open(filename, O_CREAT | O_EXCL | O_RDWR | O_BINARY, S_IRUSR | S_IWUSR); + fd = zend_file_cache_open(filename, O_CREAT | O_EXCL | O_RDWR | O_BINARY, ZCG(accel_directives).file_cache_permissions); if (fd < 0) { if (errno != EEXIST) { zend_accel_error(ACCEL_LOG_WARNING, "opcache cannot create file '%s', %s\n", filename, strerror(errno)); diff --git a/php.ini-development b/php.ini-development index afabe74ba0e4..835220d6b17a 100644 --- a/php.ini-development +++ b/php.ini-development @@ -1777,6 +1777,9 @@ ldap.max_links = -1 ; SHM reset. The default "" disables file based caching. ;opcache.file_cache= +; The permissions of the files cached, in octal notation. +;opcache.file_cache_permissions=0600 + ; Enables or disables read-only mode for the second level cache directory. ; It should improve performance for read-only containers, ; when the cache is pre-warmed and packaged alongside the application. diff --git a/php.ini-production b/php.ini-production index 04a7b699dadd..ca9097010f73 100644 --- a/php.ini-production +++ b/php.ini-production @@ -1779,6 +1779,9 @@ ldap.max_links = -1 ; SHM reset. The default "" disables file based caching. ;opcache.file_cache= +; The permissions of the files cached, in octal notation. +;opcache.file_cache_permissions=0600 + ; Enables or disables read-only mode for the second level cache directory. ; It should improve performance for read-only containers, ; when the cache is pre-warmed and packaged alongside the application.