summaryrefslogtreecommitdiff
path: root/src/snuffleupagus.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/snuffleupagus.c')
-rw-r--r--src/snuffleupagus.c201
1 files changed, 75 insertions, 126 deletions
diff --git a/src/snuffleupagus.c b/src/snuffleupagus.c
index 84ab171..6fd6f25 100644
--- a/src/snuffleupagus.c
+++ b/src/snuffleupagus.c
@@ -30,7 +30,7 @@ static inline void sp_op_array_handler(zend_op_array *const op) {
30 if (NULL == op->filename || op->fn_flags & ZEND_ACC_STRICT_TYPES) { 30 if (NULL == op->filename || op->fn_flags & ZEND_ACC_STRICT_TYPES) {
31 return; 31 return;
32 } else { 32 } else {
33 if (true == SNUFFLEUPAGUS_G(config).config_global_strict->enable) { 33 if (SPCFG(global_strict).enable) {
34 op->fn_flags |= ZEND_ACC_STRICT_TYPES; 34 op->fn_flags |= ZEND_ACC_STRICT_TYPES;
35 } 35 }
36 } 36 }
@@ -41,16 +41,15 @@ ZEND_DECLARE_MODULE_GLOBALS(snuffleupagus)
41static PHP_INI_MH(StrictMode) { 41static PHP_INI_MH(StrictMode) {
42 TSRMLS_FETCH(); 42 TSRMLS_FETCH();
43 43
44 SNUFFLEUPAGUS_G(allow_broken_configuration) = false; 44 SPG(allow_broken_configuration) = false;
45 if (new_value && zend_string_equals_literal(new_value, "1")) { 45 if (new_value && zend_string_equals_literal(new_value, "1")) {
46 SNUFFLEUPAGUS_G(allow_broken_configuration) = true; 46 SPG(allow_broken_configuration) = true;
47 } 47 }
48 return SUCCESS; 48 return SUCCESS;
49} 49}
50 50
51PHP_INI_BEGIN() 51PHP_INI_BEGIN()
52PHP_INI_ENTRY("sp.configuration_file", "", PHP_INI_SYSTEM, 52PHP_INI_ENTRY("sp.configuration_file", "", PHP_INI_SYSTEM, OnUpdateConfiguration)
53 OnUpdateConfiguration)
54PHP_INI_ENTRY("sp.allow_broken_configuration", "0", PHP_INI_SYSTEM, StrictMode) 53PHP_INI_ENTRY("sp.allow_broken_configuration", "0", PHP_INI_SYSTEM, StrictMode)
55PHP_INI_END() 54PHP_INI_END()
56 55
@@ -106,47 +105,28 @@ static PHP_GINIT_FUNCTION(snuffleupagus) {
106 snuffleupagus_globals->is_config_valid = SP_CONFIG_NONE; 105 snuffleupagus_globals->is_config_valid = SP_CONFIG_NONE;
107 snuffleupagus_globals->in_eval = 0; 106 snuffleupagus_globals->in_eval = 0;
108 107
109#define SP_INIT(F) \
110 snuffleupagus_globals->config.F = \
111 pecalloc(sizeof(*(snuffleupagus_globals->config.F)), 1, 1);
112 SP_INIT(config_random);
113 SP_INIT(config_sloppy);
114 SP_INIT(config_unserialize);
115 SP_INIT(config_readonly_exec);
116 SP_INIT(config_upload_validation);
117 SP_INIT(config_cookie);
118 SP_INIT(config_snuffleupagus);
119 SP_INIT(config_auto_cookie_secure);
120 SP_INIT(config_global_strict);
121 SP_INIT(config_disable_xxe);
122 SP_INIT(config_eval);
123 SP_INIT(config_wrapper);
124 SP_INIT(config_session);
125 SP_INIT(config_ini);
126 SP_INIT(config_disabled_functions_reg);
127 SP_INIT(config_disabled_functions_reg_ret);
128#undef SP_INIT
129
130#define SP_INIT_HT(F) \ 108#define SP_INIT_HT(F) \
131 snuffleupagus_globals->F = pemalloc(sizeof(*(snuffleupagus_globals->F)), 1); \ 109 snuffleupagus_globals->F = pemalloc(sizeof(*(snuffleupagus_globals->F)), 1); \
132 zend_hash_init(snuffleupagus_globals->F, 10, NULL, NULL, 1); 110 zend_hash_init(snuffleupagus_globals->F, 10, NULL, NULL, 1);
133 SP_INIT_HT(disabled_functions_hook); 111 SP_INIT_HT(disabled_functions_hook);
134 SP_INIT_HT(sp_internal_functions_hook); 112 SP_INIT_HT(sp_internal_functions_hook);
135 SP_INIT_HT(sp_eval_blacklist_functions_hook); 113 SP_INIT_HT(sp_eval_blacklist_functions_hook);
136 SP_INIT_HT(config.config_disabled_functions); 114 SP_INIT_HT(config_disabled_functions);
137 SP_INIT_HT(config.config_disabled_functions_hooked); 115 SP_INIT_HT(config_disabled_functions_hooked);
138 SP_INIT_HT(config.config_disabled_functions_ret); 116 SP_INIT_HT(config_disabled_functions_ret);
139 SP_INIT_HT(config.config_disabled_functions_ret_hooked); 117 SP_INIT_HT(config_disabled_functions_ret_hooked);
140 SP_INIT_HT(config.config_ini->entries); 118 SP_INIT_HT(config_ini.entries);
141#undef SP_INIT_HT 119#undef SP_INIT_HT
142 120
143#define SP_INIT_NULL(F) snuffleupagus_globals->config.F = NULL; 121#define SP_INIT_NULL(F) snuffleupagus_globals->F = NULL;
144 SP_INIT_NULL(config_disabled_functions_reg->disabled_functions); 122 SP_INIT_NULL(config_encryption_key);
145 SP_INIT_NULL(config_disabled_functions_reg_ret->disabled_functions); 123 SP_INIT_NULL(config_cookies_env_var);
146 SP_INIT_NULL(config_cookie->cookies); 124 SP_INIT_NULL(config_disabled_functions_reg.disabled_functions);
147 SP_INIT_NULL(config_eval->blacklist); 125 SP_INIT_NULL(config_disabled_functions_reg_ret.disabled_functions);
148 SP_INIT_NULL(config_eval->whitelist); 126 SP_INIT_NULL(config_cookie.cookies);
149 SP_INIT_NULL(config_wrapper->whitelist); 127 SP_INIT_NULL(config_eval.blacklist);
128 SP_INIT_NULL(config_eval.whitelist);
129 SP_INIT_NULL(config_wrapper.whitelist);
150#undef SP_INIT_NULL 130#undef SP_INIT_NULL
151} 131}
152 132
@@ -159,10 +139,10 @@ PHP_MINIT_FUNCTION(snuffleupagus) {
159 139
160PHP_MSHUTDOWN_FUNCTION(snuffleupagus) { 140PHP_MSHUTDOWN_FUNCTION(snuffleupagus) {
161 sp_log_debug("(MSHUTDOWN)"); 141 sp_log_debug("(MSHUTDOWN)");
162 unhook_functions(SNUFFLEUPAGUS_G(sp_internal_functions_hook)); 142 unhook_functions(SPG(sp_internal_functions_hook));
163 unhook_functions(SNUFFLEUPAGUS_G(disabled_functions_hook)); 143 unhook_functions(SPG(disabled_functions_hook));
164 unhook_functions(SNUFFLEUPAGUS_G(sp_eval_blacklist_functions_hook)); 144 unhook_functions(SPG(sp_eval_blacklist_functions_hook));
165 if (SNUFFLEUPAGUS_G(config).config_ini->enable) { sp_unhook_ini(); } 145 if (SPCFG(ini).enable) { sp_unhook_ini(); }
166 UNREGISTER_INI_ENTRIES(); 146 UNREGISTER_INI_ENTRIES();
167 147
168 return SUCCESS; 148 return SUCCESS;
@@ -189,57 +169,37 @@ static PHP_GSHUTDOWN_FUNCTION(snuffleupagus) {
189 FREE_HT(sp_eval_blacklist_functions_hook); 169 FREE_HT(sp_eval_blacklist_functions_hook);
190 170
191#define FREE_HT_LIST(F) \ 171#define FREE_HT_LIST(F) \
192 free_disabled_functions_hashtable(snuffleupagus_globals->config.F); \ 172 free_disabled_functions_hashtable(snuffleupagus_globals->F); \
193 FREE_HT(config.F); 173 FREE_HT(F);
194 FREE_HT_LIST(config_disabled_functions); 174 FREE_HT_LIST(config_disabled_functions);
195 FREE_HT_LIST(config_disabled_functions_hooked); 175 FREE_HT_LIST(config_disabled_functions_hooked);
196 FREE_HT_LIST(config_disabled_functions_ret); 176 FREE_HT_LIST(config_disabled_functions_ret);
197 FREE_HT_LIST(config_disabled_functions_ret_hooked); 177 FREE_HT_LIST(config_disabled_functions_ret_hooked);
198#undef FREE_HT_LIST 178#undef FREE_HT_LIST
199 179
200 free_config_ini_entries(snuffleupagus_globals->config.config_ini->entries); 180 free_config_ini_entries(snuffleupagus_globals->config_ini.entries);
201 FREE_HT(config.config_ini->entries); 181 FREE_HT(config_ini.entries);
202#undef FREE_HT 182#undef FREE_HT
203 183
204#define FREE_LST_DISABLE(L) \ 184 sp_list_free(snuffleupagus_globals->config_disabled_functions_reg.disabled_functions, sp_free_disabled_function);
205 sp_list_free(snuffleupagus_globals->config.L, sp_free_disabled_function); 185 sp_list_free(snuffleupagus_globals->config_disabled_functions_reg_ret.disabled_functions, sp_free_disabled_function);
206 FREE_LST_DISABLE(config_disabled_functions_reg->disabled_functions); 186 sp_list_free(snuffleupagus_globals->config_cookie.cookies, sp_free_cookie);
207 FREE_LST_DISABLE(config_disabled_functions_reg_ret->disabled_functions);
208#undef FREE_LST_DISABLE
209
210 sp_list_free(snuffleupagus_globals->config.config_cookie->cookies, sp_free_cookie);
211 187
212#define FREE_LST(L) sp_list_free(snuffleupagus_globals->config.L, sp_free_zstr); 188#define FREE_LST(L) sp_list_free(snuffleupagus_globals->L, sp_free_zstr);
213 FREE_LST(config_eval->blacklist); 189 FREE_LST(config_eval.blacklist);
214 FREE_LST(config_eval->whitelist); 190 FREE_LST(config_eval.whitelist);
215 FREE_LST(config_wrapper->whitelist); 191 FREE_LST(config_wrapper.whitelist);
216#undef FREE_LST 192#undef FREE_LST
217 193
218 194
219#define FREE_CFG(C) pefree(snuffleupagus_globals->config.C, 1); 195// #define FREE_CFG(C) pefree(snuffleupagus_globals->config.C, 1);
220#define FREE_CFG_ZSTR(C) sp_free_zstr(snuffleupagus_globals->config.C); 196#define FREE_CFG_ZSTR(C) sp_free_zstr(snuffleupagus_globals->C);
221 FREE_CFG(config_random); 197 FREE_CFG_ZSTR(config_unserialize.dump);
222 FREE_CFG(config_sloppy); 198 FREE_CFG_ZSTR(config_unserialize.textual_representation);
223 FREE_CFG_ZSTR(config_unserialize->dump); 199 FREE_CFG_ZSTR(config_upload_validation.script);
224 FREE_CFG_ZSTR(config_unserialize->textual_representation); 200 FREE_CFG_ZSTR(config_eval.dump);
225 FREE_CFG(config_unserialize); 201 FREE_CFG_ZSTR(config_eval.textual_representation);
226 FREE_CFG(config_readonly_exec); 202// #undef FREE_CFG
227 FREE_CFG_ZSTR(config_upload_validation->script);
228 FREE_CFG(config_upload_validation);
229 FREE_CFG(config_cookie);
230 FREE_CFG(config_snuffleupagus);
231 FREE_CFG(config_auto_cookie_secure);
232 FREE_CFG(config_global_strict);
233 FREE_CFG(config_disable_xxe);
234 FREE_CFG_ZSTR(config_eval->dump);
235 FREE_CFG_ZSTR(config_eval->textual_representation);
236 FREE_CFG(config_eval);
237 FREE_CFG(config_wrapper);
238 FREE_CFG(config_session);
239 FREE_CFG(config_ini);
240 FREE_CFG(config_disabled_functions_reg);
241 FREE_CFG(config_disabled_functions_reg_ret);
242#undef FREE_CFG
243#undef FREE_CFG_ZSTR 203#undef FREE_CFG_ZSTR
244 204
245#ifdef SP_DEBUG_STDERR 205#ifdef SP_DEBUG_STDERR
@@ -251,35 +211,32 @@ static PHP_GSHUTDOWN_FUNCTION(snuffleupagus) {
251} 211}
252 212
253PHP_RINIT_FUNCTION(snuffleupagus) { 213PHP_RINIT_FUNCTION(snuffleupagus) {
254 SNUFFLEUPAGUS_G(execution_depth) = 0; 214 SPG(execution_depth) = 0;
215 SPG(in_eval) = 0;
255 216
256 const sp_config_wrapper *const config_wrapper = 217 const sp_config_wrapper *const config_wrapper = &(SPCFG(wrapper));
257 SNUFFLEUPAGUS_G(config).config_wrapper;
258#if defined(COMPILE_DL_SNUFFLEUPAGUS) && defined(ZTS) 218#if defined(COMPILE_DL_SNUFFLEUPAGUS) && defined(ZTS)
259 ZEND_TSRMLS_CACHE_UPDATE(); 219 ZEND_TSRMLS_CACHE_UPDATE();
260#endif 220#endif
261 221
262 if (!SNUFFLEUPAGUS_G(allow_broken_configuration)) { 222 if (!SPG(allow_broken_configuration)) {
263 if (SNUFFLEUPAGUS_G(is_config_valid) == SP_CONFIG_INVALID) { 223 if (SPG(is_config_valid) == SP_CONFIG_INVALID) {
264 sp_log_err("config", "Invalid configuration file"); 224 sp_log_err("config", "Invalid configuration file");
265 } else if (SNUFFLEUPAGUS_G(is_config_valid) == SP_CONFIG_NONE) { 225 } else if (SPG(is_config_valid) == SP_CONFIG_NONE) {
266 sp_log_warn("config", 226 sp_log_warn("config",
267 "No configuration specificed via sp.configuration_file"); 227 "No configuration specificed via sp.configuration_file");
268 } 228 }
269 } 229 }
270 230
271 // We need to disable wrappers loaded by extensions loaded after 231 // We need to disable wrappers loaded by extensions loaded after SNUFFLEUPAGUS.
272 // SNUFFLEUPAGUS.
273 if (config_wrapper->enabled && 232 if (config_wrapper->enabled &&
274 zend_hash_num_elements(php_stream_get_url_stream_wrappers_hash()) != 233 zend_hash_num_elements(php_stream_get_url_stream_wrappers_hash()) != config_wrapper->num_wrapper) {
275 config_wrapper->num_wrapper) {
276 sp_disable_wrapper(); 234 sp_disable_wrapper();
277 } 235 }
278 236
279 if (NULL != SNUFFLEUPAGUS_G(config).config_snuffleupagus->encryption_key) { 237 if (NULL != SPCFG(encryption_key)) {
280 if (NULL != SNUFFLEUPAGUS_G(config).config_cookie->cookies) { 238 if (NULL != SPCFG(cookie).cookies) {
281 zend_hash_apply_with_arguments( 239 zend_hash_apply_with_arguments(Z_ARRVAL(PG(http_globals)[TRACK_VARS_COOKIE]), decrypt_cookie, 0);
282 Z_ARRVAL(PG(http_globals)[TRACK_VARS_COOKIE]), decrypt_cookie, 0);
283 } 240 }
284 } 241 }
285 return SUCCESS; 242 return SUCCESS;
@@ -289,7 +246,7 @@ PHP_RSHUTDOWN_FUNCTION(snuffleupagus) { return SUCCESS; }
289 246
290PHP_MINFO_FUNCTION(snuffleupagus) { 247PHP_MINFO_FUNCTION(snuffleupagus) {
291 const char *valid_config; 248 const char *valid_config;
292 switch (SNUFFLEUPAGUS_G(is_config_valid)) { 249 switch (SPG(is_config_valid)) {
293 case SP_CONFIG_VALID: 250 case SP_CONFIG_VALID:
294 valid_config = "yes"; 251 valid_config = "yes";
295 break; 252 break;
@@ -303,7 +260,7 @@ PHP_MINFO_FUNCTION(snuffleupagus) {
303 php_info_print_table_start(); 260 php_info_print_table_start();
304 php_info_print_table_row( 261 php_info_print_table_row(
305 2, "snuffleupagus support", 262 2, "snuffleupagus support",
306 SNUFFLEUPAGUS_G(is_config_valid) ? "enabled" : "disabled"); 263 SPG(is_config_valid) ? "enabled" : "disabled");
307 php_info_print_table_row(2, "Version", PHP_SNUFFLEUPAGUS_VERSION "-sng (with Suhosin-NG patches)"); 264 php_info_print_table_row(2, "Version", PHP_SNUFFLEUPAGUS_VERSION "-sng (with Suhosin-NG patches)");
308 php_info_print_table_row(2, "Valid config", valid_config); 265 php_info_print_table_row(2, "Valid config", valid_config);
309 php_info_print_table_end(); 266 php_info_print_table_end();
@@ -328,14 +285,14 @@ static PHP_INI_MH(OnUpdateConfiguration) {
328 285
329 glob_t globbuf; 286 glob_t globbuf;
330 if (0 != glob(config_file, GLOB_NOCHECK, NULL, &globbuf)) { 287 if (0 != glob(config_file, GLOB_NOCHECK, NULL, &globbuf)) {
331 SNUFFLEUPAGUS_G(is_config_valid) = SP_CONFIG_INVALID; 288 SPG(is_config_valid) = SP_CONFIG_INVALID;
332 globfree(&globbuf); 289 globfree(&globbuf);
333 return FAILURE; 290 return FAILURE;
334 } 291 }
335 292
336 for (size_t i = 0; globbuf.gl_pathv[i]; i++) { 293 for (size_t i = 0; globbuf.gl_pathv[i]; i++) {
337 if (sp_parse_config(globbuf.gl_pathv[i]) != SUCCESS) { 294 if (sp_parse_config(globbuf.gl_pathv[i]) != SUCCESS) {
338 SNUFFLEUPAGUS_G(is_config_valid) = SP_CONFIG_INVALID; 295 SPG(is_config_valid) = SP_CONFIG_INVALID;
339 globfree(&globbuf); 296 globfree(&globbuf);
340 return FAILURE; 297 return FAILURE;
341 } 298 }
@@ -343,34 +300,34 @@ static PHP_INI_MH(OnUpdateConfiguration) {
343 globfree(&globbuf); 300 globfree(&globbuf);
344 } 301 }
345 302
346 SNUFFLEUPAGUS_G(is_config_valid) = SP_CONFIG_VALID; 303 SPG(is_config_valid) = SP_CONFIG_VALID;
347 304
348 if ((SNUFFLEUPAGUS_G(config).config_sloppy->enable)) { 305 if (SPCFG(sloppy).enable) {
349 hook_sloppy(); 306 hook_sloppy();
350 } 307 }
351 308
352 if (SNUFFLEUPAGUS_G(config).config_random->enable) { 309 if (SPCFG(random).enable) {
353 hook_rand(); 310 hook_rand();
354 } 311 }
355 312
356 if (SNUFFLEUPAGUS_G(config).config_upload_validation->enable) { 313 if (SPCFG(upload_validation).enable) {
357 hook_upload(); 314 hook_upload();
358 } 315 }
359 316
360 if (SNUFFLEUPAGUS_G(config).config_disable_xxe->enable == 0) { 317 if (SPCFG(disable_xxe).enable == 0) {
361 hook_libxml_disable_entity_loader(); 318 hook_libxml_disable_entity_loader();
362 } 319 }
363 320
364 if (SNUFFLEUPAGUS_G(config).config_wrapper->enabled) { 321 if (SPCFG(wrapper).enabled) {
365 hook_stream_wrappers(); 322 hook_stream_wrappers();
366 } 323 }
367 324
368 if (SNUFFLEUPAGUS_G(config).config_session->encrypt || SNUFFLEUPAGUS_G(config).config_session->sid_min_length || SNUFFLEUPAGUS_G(config).config_session->sid_max_length) { 325 if (SPCFG(session).encrypt || SPCFG(session).sid_min_length || SPCFG(session).sid_max_length) {
369 hook_session(); 326 hook_session();
370 } 327 }
371 328
372 if (NULL != SNUFFLEUPAGUS_G(config).config_snuffleupagus->encryption_key) { 329 if (NULL != SPCFG(encryption_key)) {
373 if (SNUFFLEUPAGUS_G(config).config_unserialize->enable) { 330 if (SPCFG(unserialize).enable) {
374 hook_serialize(); 331 hook_serialize();
375 } 332 }
376 } 333 }
@@ -379,13 +336,13 @@ static PHP_INI_MH(OnUpdateConfiguration) {
379 hook_execute(); 336 hook_execute();
380 hook_cookies(); 337 hook_cookies();
381 338
382 if (SNUFFLEUPAGUS_G(config).config_ini->enable) { 339 if (SPCFG(ini).enable) {
383 sp_hook_ini(); 340 sp_hook_ini();
384 } 341 }
385 342
386 sp_hook_register_server_variables(); 343 sp_hook_register_server_variables();
387 344
388 if (true == SNUFFLEUPAGUS_G(config).config_global_strict->enable) { 345 if (SPCFG(global_strict).enable) {
389 if (!zend_get_extension(PHP_SNUFFLEUPAGUS_EXTNAME)) { 346 if (!zend_get_extension(PHP_SNUFFLEUPAGUS_EXTNAME)) {
390 zend_extension_entry.startup = NULL; 347 zend_extension_entry.startup = NULL;
391 zend_register_extension(&zend_extension_entry, NULL); 348 zend_register_extension(&zend_extension_entry, NULL);
@@ -395,26 +352,18 @@ static PHP_INI_MH(OnUpdateConfiguration) {
395 } 352 }
396 353
397 // If `zend_write_default` is not NULL it is already hooked. 354 // If `zend_write_default` is not NULL it is already hooked.
398 if ((zend_hash_str_find( 355 if ((zend_hash_str_find(SPCFG(disabled_functions_hooked), ZEND_STRL("echo")) ||
399 SNUFFLEUPAGUS_G(config).config_disabled_functions_hooked, "echo", 356 zend_hash_str_find(SPCFG(disabled_functions_ret_hooked), ZEND_STRL("echo"))) &&
400 sizeof("echo") - 1) ||
401 zend_hash_str_find(
402 SNUFFLEUPAGUS_G(config).config_disabled_functions_ret_hooked, "echo",
403 sizeof("echo") - 1)) &&
404 NULL == zend_write_default && zend_write != hook_echo) { 357 NULL == zend_write_default && zend_write != hook_echo) {
405 zend_write_default = zend_write; 358 zend_write_default = zend_write;
406 zend_write = hook_echo; 359 zend_write = hook_echo;
407 } 360 }
408 361
409 SNUFFLEUPAGUS_G(config).hook_execute = 362 SPG(hook_execute) = SPCFG(max_execution_depth) > 0 ||
410 SNUFFLEUPAGUS_G(config) 363 SPCFG(disabled_functions_reg).disabled_functions ||
411 .config_disabled_functions_reg->disabled_functions || 364 SPCFG(disabled_functions_reg_ret).disabled_functions ||
412 SNUFFLEUPAGUS_G(config) 365 (SPCFG(disabled_functions) && zend_hash_num_elements(SPCFG(disabled_functions))) ||
413 .config_disabled_functions_reg_ret->disabled_functions || 366 (SPCFG(disabled_functions) && zend_hash_num_elements(SPCFG(disabled_functions_ret)));
414 zend_hash_num_elements(
415 SNUFFLEUPAGUS_G(config).config_disabled_functions) ||
416 zend_hash_num_elements(
417 SNUFFLEUPAGUS_G(config).config_disabled_functions_ret);
418 367
419 return SUCCESS; 368 return SUCCESS;
420} 369}