summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Fuhrmannek2021-11-30 19:38:34 +0100
committerBen Fuhrmannek2021-11-30 19:38:34 +0100
commit6095651e2caa729ff56ae5a53c908b09e5f7dc29 (patch)
tree0bb9907ea7142701c206b00a135c0c0d96c9ca39
parenta870b1547fceb5f58d56f1a1646ab1e897d28238 (diff)
PHP 8.1 compatibility with streams/includes + fix for ticks
-rw-r--r--src/snuffleupagus.c1
-rw-r--r--src/sp_disabled_functions.c12
-rw-r--r--src/sp_execute.c40
-rw-r--r--src/tests/ini/config/sp-policy-drop.ini2
-rw-r--r--src/tests/ini/config/sp-policy-silent-fail.ini2
-rw-r--r--src/tests/ini/config/sp.ini3
-rw-r--r--src/tests/ini/ini_min_policy_drop.phpt4
-rw-r--r--src/tests/ini/ini_min_policy_silent_fail.phpt4
-rw-r--r--src/tests/ini/ini_minmax.phpt24
9 files changed, 55 insertions, 37 deletions
diff --git a/src/snuffleupagus.c b/src/snuffleupagus.c
index e3ecd72..01a0b01 100644
--- a/src/snuffleupagus.c
+++ b/src/snuffleupagus.c
@@ -370,7 +370,6 @@ static PHP_INI_MH(OnUpdateConfiguration) {
370 370
371 if (SPCFG(show_old_php_warning)) { 371 if (SPCFG(show_old_php_warning)) {
372 time_t ts = time(NULL); 372 time_t ts = time(NULL);
373 sp_log_debug("foo");
374 if (PHP_VERSION_ID < 70300 || 373 if (PHP_VERSION_ID < 70300 ||
375 PHP_VERSION_ID < 70400 && ts >= (time_t)1638745200L || 374 PHP_VERSION_ID < 70400 && ts >= (time_t)1638745200L ||
376 PHP_VERSION_ID < 80000 && ts >= (time_t)1669590000L || 375 PHP_VERSION_ID < 80000 && ts >= (time_t)1669590000L ||
diff --git a/src/sp_disabled_functions.c b/src/sp_disabled_functions.c
index 4ef72bf..a3b3e99 100644
--- a/src/sp_disabled_functions.c
+++ b/src/sp_disabled_functions.c
@@ -498,11 +498,9 @@ static int hook_functions_regexp(const sp_list_node* config) {
498 assert(function_name || function_name_regexp); 498 assert(function_name || function_name_regexp);
499 499
500 if (function_name) { 500 if (function_name) {
501 HOOK_FUNCTION(ZSTR_VAL(function_name), disabled_functions_hook, 501 HOOK_FUNCTION(ZSTR_VAL(function_name), disabled_functions_hook, PHP_FN(check_disabled_function));
502 PHP_FN(check_disabled_function));
503 } else { 502 } else {
504 HOOK_FUNCTION_BY_REGEXP(function_name_regexp, disabled_functions_hook, 503 HOOK_FUNCTION_BY_REGEXP(function_name_regexp, disabled_functions_hook, PHP_FN(check_disabled_function));
505 PHP_FN(check_disabled_function));
506 } 504 }
507 505
508 config = config->next; 506 config = config->next;
@@ -515,10 +513,8 @@ static void hook_functions(HashTable* to_hook_ht, HashTable* hooked_ht) {
515 zval* value; 513 zval* value;
516 514
517 ZEND_HASH_FOREACH_STR_KEY_VAL(to_hook_ht, key, value) { 515 ZEND_HASH_FOREACH_STR_KEY_VAL(to_hook_ht, key, value) {
518 bool hooked = HOOK_FUNCTION(ZSTR_VAL(key), disabled_functions_hook, 516 bool hooked = HOOK_FUNCTION(ZSTR_VAL(key), disabled_functions_hook, PHP_FN(check_disabled_function));
519 PHP_FN(check_disabled_function)); 517 bool is_builtin = check_is_builtin_name(((sp_list_node*)Z_PTR_P(value))->data);
520 bool is_builtin =
521 check_is_builtin_name(((sp_list_node*)Z_PTR_P(value))->data);
522 if (hooked || is_builtin) { 518 if (hooked || is_builtin) {
523 zend_symtable_add_new(hooked_ht, key, value); 519 zend_symtable_add_new(hooked_ht, key, value);
524 zend_hash_del(to_hook_ht, key); 520 zend_hash_del(to_hook_ht, key);
diff --git a/src/sp_execute.c b/src/sp_execute.c
index ccb7508..f540119 100644
--- a/src/sp_execute.c
+++ b/src/sp_execute.c
@@ -3,8 +3,11 @@
3static void (*orig_execute_ex)(zend_execute_data *execute_data) = NULL; 3static void (*orig_execute_ex)(zend_execute_data *execute_data) = NULL;
4static void (*orig_zend_execute_internal)(zend_execute_data *execute_data, 4static void (*orig_zend_execute_internal)(zend_execute_data *execute_data,
5 zval *return_value) = NULL; 5 zval *return_value) = NULL;
6static int (*orig_zend_stream_open)(const char *filename, 6#if PHP_VERSION_ID < 80100
7 zend_file_handle *handle) = NULL; 7static int (*orig_zend_stream_open)(const char *filename, zend_file_handle *handle) = NULL;
8#else
9static zend_result (*orig_zend_stream_open)(zend_file_handle *handle) = NULL;
10#endif
8 11
9// FIXME handle symlink 12// FIXME handle symlink
10ZEND_COLD static inline void terminate_if_writable(const char *filename) { 13ZEND_COLD static inline void terminate_if_writable(const char *filename) {
@@ -168,6 +171,7 @@ static void sp_execute_ex(zend_execute_data *execute_data) {
168 case ZEND_DO_FCALL_BY_NAME: 171 case ZEND_DO_FCALL_BY_NAME:
169 case ZEND_DO_ICALL: 172 case ZEND_DO_ICALL:
170 case ZEND_DO_UCALL: 173 case ZEND_DO_UCALL:
174 case ZEND_TICKS:
171 should_disable_ht(execute_data, function_name, NULL, NULL, 175 should_disable_ht(execute_data, function_name, NULL, NULL,
172 config_disabled_functions_reg, 176 config_disabled_functions_reg,
173 config_disabled_functions); 177 config_disabled_functions);
@@ -209,21 +213,21 @@ static void sp_zend_execute_internal(INTERNAL_FUNCTION_PARAMETERS) {
209 } 213 }
210} 214}
211 215
212static int sp_stream_open(const char *filename, zend_file_handle *handle) { 216static inline void sp_stream_open_checks(zend_string *zend_filename, zend_file_handle *handle) {
213 zend_execute_data const *const data = EG(current_execute_data); 217 zend_execute_data const *const data = EG(current_execute_data);
214 218
215 if ((NULL == data) || (NULL == data->opline) || 219 if ((NULL == data) || (NULL == data->opline) ||
216 (data->func->type != ZEND_USER_FUNCTION)) { 220 (data->func->type != ZEND_USER_FUNCTION)) {
217 goto end; 221 return;
218 } 222 }
219 223
220 zend_string *zend_filename = zend_string_init(filename, strlen(filename), 0); 224 // zend_string *zend_filename = zend_string_init(filename, strlen(filename), 0);
221 const HashTable *disabled_functions_hooked = SPCFG(disabled_functions_hooked); 225 const HashTable *disabled_functions_hooked = SPCFG(disabled_functions_hooked);
222 226
223 switch (data->opline->opcode) { 227 switch (data->opline->opcode) {
224 case ZEND_INCLUDE_OR_EVAL: 228 case ZEND_INCLUDE_OR_EVAL:
225 if (SPCFG(readonly_exec).enable) { 229 if (SPCFG(readonly_exec).enable) {
226 terminate_if_writable(filename); 230 terminate_if_writable(ZSTR_VAL(zend_filename));
227 } 231 }
228 switch (data->opline->extended_value) { 232 switch (data->opline->extended_value) {
229 case ZEND_INCLUDE: 233 case ZEND_INCLUDE:
@@ -253,12 +257,32 @@ static int sp_stream_open(const char *filename, zend_file_handle *handle) {
253 EMPTY_SWITCH_DEFAULT_CASE(); // LCOV_EXCL_LINE 257 EMPTY_SWITCH_DEFAULT_CASE(); // LCOV_EXCL_LINE
254 } 258 }
255 } 259 }
256 efree(zend_filename); 260 // efree(zend_filename);
261
262// end:
263 // return orig_zend_stream_open(filename, handle);
264}
265
266#if PHP_VERSION_ID < 80100
267
268static int sp_stream_open(const char *filename, zend_file_handle *handle) {
269 zend_string *zend_filename = zend_string_init(filename, strlen(filename), 0);
257 270
258end: 271 sp_stream_open_checks(zend_filename, handle);
272
273 zend_string_release_ex(zend_filename, 0);
259 return orig_zend_stream_open(filename, handle); 274 return orig_zend_stream_open(filename, handle);
260} 275}
261 276
277#else // PHP >= 8.1
278
279static zend_result sp_stream_open(zend_file_handle *handle) {
280 sp_stream_open_checks(handle->filename, handle);
281 return orig_zend_stream_open(handle);
282}
283
284#endif
285
262int hook_execute(void) { 286int hook_execute(void) {
263 TSRMLS_FETCH(); 287 TSRMLS_FETCH();
264 288
diff --git a/src/tests/ini/config/sp-policy-drop.ini b/src/tests/ini/config/sp-policy-drop.ini
index 1c28030..4b1e374 100644
--- a/src/tests/ini/config/sp-policy-drop.ini
+++ b/src/tests/ini/config/sp-policy-drop.ini
@@ -1,3 +1,3 @@
1sp.ini_protection.enable(); 1sp.ini_protection.enable();
2sp.ini_protection.policy_drop(); 2sp.ini_protection.policy_drop();
3sp.ini.key("log_errors_max_len").min("200").max("2000"); 3sp.ini.key("max_execution_time").min("30").max("300");
diff --git a/src/tests/ini/config/sp-policy-silent-fail.ini b/src/tests/ini/config/sp-policy-silent-fail.ini
index 8236077..2123837 100644
--- a/src/tests/ini/config/sp-policy-silent-fail.ini
+++ b/src/tests/ini/config/sp-policy-silent-fail.ini
@@ -1,3 +1,3 @@
1sp.ini_protection.enable(); 1sp.ini_protection.enable();
2sp.ini_protection.policy_silent_fail(); 2sp.ini_protection.policy_silent_fail();
3sp.ini.key("log_errors_max_len").min("200").max("2000"); 3sp.ini.key("max_execution_time").min("30").max("300");
diff --git a/src/tests/ini/config/sp.ini b/src/tests/ini/config/sp.ini
index 3022e37..86a63a7 100644
--- a/src/tests/ini/config/sp.ini
+++ b/src/tests/ini/config/sp.ini
@@ -1,7 +1,6 @@
1sp.ini_protection.enable(); 1sp.ini_protection.enable();
2 2
3sp.ini.key("log_errors_max_len").min("200").max("2000"); 3sp.ini.key("max_execution_time").min("30").max("300");
4sp.ini.key("max_execution_time").min("30").max("600");
5sp.ini.key("highlight.comment").regexp("^#[0-9a-fA-F]{6}$"); 4sp.ini.key("highlight.comment").regexp("^#[0-9a-fA-F]{6}$");
6sp.ini.key("default_mimetype").set("text/plain").ro(); 5sp.ini.key("default_mimetype").set("text/plain").ro();
7 6
diff --git a/src/tests/ini/ini_min_policy_drop.phpt b/src/tests/ini/ini_min_policy_drop.phpt
index 9dddcc4..ef40ebc 100644
--- a/src/tests/ini/ini_min_policy_drop.phpt
+++ b/src/tests/ini/ini_min_policy_drop.phpt
@@ -6,8 +6,8 @@ INI protection .min() + .policy_drop()
6sp.configuration_file={PWD}/config/sp-policy-drop.ini 6sp.configuration_file={PWD}/config/sp-policy-drop.ini
7--FILE-- 7--FILE--
8<?php 8<?php
9var_dump(ini_set("log_errors_max_len", "199") === false); 9var_dump(ini_set("max_execution_time", "29") === false);
10var_dump(ini_get("log_errors_max_len")); 10var_dump(ini_get("max_execution_time"));
11?> 11?>
12--EXPECTF-- 12--EXPECTF--
13Fatal error: [snuffleupagus][0.0.0.0][ini_protection][drop] INI value out of range in %a/ini_min_policy_drop.php on line 2 13Fatal error: [snuffleupagus][0.0.0.0][ini_protection][drop] INI value out of range in %a/ini_min_policy_drop.php on line 2
diff --git a/src/tests/ini/ini_min_policy_silent_fail.phpt b/src/tests/ini/ini_min_policy_silent_fail.phpt
index 8ef780d..d0117a7 100644
--- a/src/tests/ini/ini_min_policy_silent_fail.phpt
+++ b/src/tests/ini/ini_min_policy_silent_fail.phpt
@@ -6,8 +6,8 @@ INI protection .min() + .policy_silent_fail()
6sp.configuration_file={PWD}/config/sp-policy-silent-fail.ini 6sp.configuration_file={PWD}/config/sp-policy-silent-fail.ini
7--FILE-- 7--FILE--
8<?php 8<?php
9var_dump(ini_set("log_errors_max_len", "199") === false); 9var_dump(ini_set("max_execution_time", "29") === false);
10var_dump(ini_get("log_errors_max_len")); 10var_dump(ini_get("max_execution_time"));
11?> 11?>
12--EXPECTF-- 12--EXPECTF--
13bool(true) 13bool(true)
diff --git a/src/tests/ini/ini_minmax.phpt b/src/tests/ini/ini_minmax.phpt
index fc93075..4cd6bc4 100644
--- a/src/tests/ini/ini_minmax.phpt
+++ b/src/tests/ini/ini_minmax.phpt
@@ -6,29 +6,29 @@ INI protection .min()/.max()
6sp.configuration_file={PWD}/config/sp.ini 6sp.configuration_file={PWD}/config/sp.ini
7--FILE-- 7--FILE--
8<?php 8<?php
9var_dump(ini_set("log_errors_max_len", "200") === false); 9var_dump(ini_set("max_execution_time", "30") === false);
10var_dump(ini_get("log_errors_max_len")); 10var_dump(ini_get("max_execution_time"));
11 11
12var_dump(ini_set("log_errors_max_len", "2000") === false); 12var_dump(ini_set("max_execution_time", "300") === false);
13var_dump(ini_get("log_errors_max_len")); 13var_dump(ini_get("max_execution_time"));
14 14
15var_dump(ini_set("log_errors_max_len", "199") === false); 15var_dump(ini_set("max_execution_time", "29") === false);
16var_dump(ini_get("log_errors_max_len")); 16var_dump(ini_get("max_execution_time"));
17 17
18var_dump(ini_set("log_errors_max_len", "2001") === false); 18var_dump(ini_set("max_execution_time", "301") === false);
19var_dump(ini_get("log_errors_max_len")); 19var_dump(ini_get("max_execution_time"));
20 20
21?> 21?>
22--EXPECTF-- 22--EXPECTF--
23bool(false) 23bool(false)
24string(3) "200" 24string(2) "30"
25bool(false) 25bool(false)
26string(4) "2000" 26string(3) "300"
27 27
28Warning: [snuffleupagus][0.0.0.0][ini_protection][log] INI value out of range in %a/ini_minmax.php on line 8 28Warning: [snuffleupagus][0.0.0.0][ini_protection][log] INI value out of range in %a/ini_minmax.php on line 8
29bool(true) 29bool(true)
30string(4) "2000" 30string(3) "300"
31 31
32Warning: [snuffleupagus][0.0.0.0][ini_protection][log] INI value out of range in %a/ini_minmax.php on line 11 32Warning: [snuffleupagus][0.0.0.0][ini_protection][log] INI value out of range in %a/ini_minmax.php on line 11
33bool(true) 33bool(true)
34string(4) "2000" \ No newline at end of file 34string(3) "300" \ No newline at end of file