summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBen Fuhrmannek2021-08-02 19:19:23 +0200
committerBen Fuhrmannek2021-08-02 19:19:23 +0200
commitae4ac9f69de3120004557824e0d766fe8140b27d (patch)
treeef97751ab54357d5d74859b870ce84f4c6d044df /src
parent4cda0120313dfd5d71236f6faf87416e93f5f89c (diff)
properly free memory on shutdown
Diffstat (limited to 'src')
-rw-r--r--src/snuffleupagus.c77
-rw-r--r--src/sp_config.c70
-rw-r--r--src/sp_config.h10
-rw-r--r--src/sp_list.c16
-rw-r--r--src/sp_list.h3
-rw-r--r--src/sp_var_parser.c2
6 files changed, 108 insertions, 70 deletions
diff --git a/src/snuffleupagus.c b/src/snuffleupagus.c
index 7bf3649..d8a86b5 100644
--- a/src/snuffleupagus.c
+++ b/src/snuffleupagus.c
@@ -69,7 +69,7 @@ ZEND_DLEXPORT zend_extension zend_extension_entry = {
69 NULL, /* op_array_dtor_func_t */ 69 NULL, /* op_array_dtor_func_t */
70 STANDARD_ZEND_EXTENSION_PROPERTIES}; 70 STANDARD_ZEND_EXTENSION_PROPERTIES};
71 71
72PHP_GINIT_FUNCTION(snuffleupagus) { 72static PHP_GINIT_FUNCTION(snuffleupagus) {
73 snuffleupagus_globals->is_config_valid = SP_CONFIG_NONE; 73 snuffleupagus_globals->is_config_valid = SP_CONFIG_NONE;
74 snuffleupagus_globals->in_eval = 0; 74 snuffleupagus_globals->in_eval = 0;
75 75
@@ -88,21 +88,21 @@ PHP_GINIT_FUNCTION(snuffleupagus) {
88#define SP_INIT(F) \ 88#define SP_INIT(F) \
89 snuffleupagus_globals->config.F = \ 89 snuffleupagus_globals->config.F = \
90 pecalloc(sizeof(*(snuffleupagus_globals->config.F)), 1, 1); 90 pecalloc(sizeof(*(snuffleupagus_globals->config.F)), 1, 1);
91 SP_INIT(config_unserialize);
92 SP_INIT(config_random); 91 SP_INIT(config_random);
93 SP_INIT(config_sloppy); 92 SP_INIT(config_sloppy);
93 SP_INIT(config_unserialize);
94 SP_INIT(config_readonly_exec); 94 SP_INIT(config_readonly_exec);
95 SP_INIT(config_global_strict);
96 SP_INIT(config_auto_cookie_secure);
97 SP_INIT(config_snuffleupagus);
98 SP_INIT(config_disable_xxe);
99 SP_INIT(config_upload_validation); 95 SP_INIT(config_upload_validation);
100 SP_INIT(config_disabled_functions_reg);
101 SP_INIT(config_disabled_functions_reg_ret);
102 SP_INIT(config_cookie); 96 SP_INIT(config_cookie);
103 SP_INIT(config_session); 97 SP_INIT(config_snuffleupagus);
98 SP_INIT(config_auto_cookie_secure);
99 SP_INIT(config_global_strict);
100 SP_INIT(config_disable_xxe);
104 SP_INIT(config_eval); 101 SP_INIT(config_eval);
105 SP_INIT(config_wrapper); 102 SP_INIT(config_wrapper);
103 SP_INIT(config_session);
104 SP_INIT(config_disabled_functions_reg);
105 SP_INIT(config_disabled_functions_reg_ret);
106#undef SP_INIT 106#undef SP_INIT
107 107
108#define SP_INIT_NULL(F) snuffleupagus_globals->config.F = NULL; 108#define SP_INIT_NULL(F) snuffleupagus_globals->config.F = NULL;
@@ -121,21 +121,27 @@ PHP_MINIT_FUNCTION(snuffleupagus) {
121 return SUCCESS; 121 return SUCCESS;
122} 122}
123 123
124static void free_disabled_functions_hashtable(HashTable *const ht) { 124PHP_MSHUTDOWN_FUNCTION(snuffleupagus) {
125 UNREGISTER_INI_ENTRIES();
126
127 return SUCCESS;
128}
129
130static inline void free_disabled_functions_hashtable(HashTable *const ht) {
125 void *ptr = NULL; 131 void *ptr = NULL;
126 ZEND_HASH_FOREACH_PTR(ht, ptr) { sp_list_free(ptr); } 132 ZEND_HASH_FOREACH_PTR(ht, ptr) { sp_list_free(ptr, sp_free_disabled_function); }
127 ZEND_HASH_FOREACH_END(); 133 ZEND_HASH_FOREACH_END();
128} 134}
129 135
130PHP_MSHUTDOWN_FUNCTION(snuffleupagus) { 136static PHP_GSHUTDOWN_FUNCTION(snuffleupagus) {
131#define FREE_HT(F) \ 137#define FREE_HT(F) \
132 zend_hash_destroy(SNUFFLEUPAGUS_G(F)); \ 138 zend_hash_destroy(snuffleupagus_globals->F); \
133 pefree(SNUFFLEUPAGUS_G(F), 1); 139 pefree(snuffleupagus_globals->F, 1);
134 FREE_HT(disabled_functions_hook); 140 FREE_HT(disabled_functions_hook);
135 FREE_HT(sp_eval_blacklist_functions_hook); 141 FREE_HT(sp_eval_blacklist_functions_hook);
136 142
137#define FREE_HT_LIST(F) \ 143#define FREE_HT_LIST(F) \
138 free_disabled_functions_hashtable(SNUFFLEUPAGUS_G(config).F); \ 144 free_disabled_functions_hashtable(snuffleupagus_globals->config.F); \
139 FREE_HT(config.F); 145 FREE_HT(config.F);
140 FREE_HT_LIST(config_disabled_functions); 146 FREE_HT_LIST(config_disabled_functions);
141 FREE_HT_LIST(config_disabled_functions_hooked); 147 FREE_HT_LIST(config_disabled_functions_hooked);
@@ -145,44 +151,43 @@ PHP_MSHUTDOWN_FUNCTION(snuffleupagus) {
145#undef FREE_HT 151#undef FREE_HT
146 152
147#define FREE_LST_DISABLE(L) \ 153#define FREE_LST_DISABLE(L) \
148 do { \ 154 sp_list_free(snuffleupagus_globals->config.L, sp_free_disabled_function);
149 sp_list_node *_n = SNUFFLEUPAGUS_G(config).L; \
150 sp_disabled_function_list_free(_n); \
151 sp_list_free(_n); \
152 } while (0)
153 FREE_LST_DISABLE(config_disabled_functions_reg->disabled_functions); 155 FREE_LST_DISABLE(config_disabled_functions_reg->disabled_functions);
154 FREE_LST_DISABLE(config_disabled_functions_reg_ret->disabled_functions); 156 FREE_LST_DISABLE(config_disabled_functions_reg_ret->disabled_functions);
155#undef FREE_LST_DISABLE 157#undef FREE_LST_DISABLE
156 158
157 sp_list_node *_n = SNUFFLEUPAGUS_G(config).config_cookie->cookies; 159 sp_list_free(snuffleupagus_globals->config.config_cookie->cookies, sp_free_cookie);
158 sp_cookie_list_free(_n);
159 sp_list_free(_n);
160 160
161#define FREE_LST(L) sp_list_free(SNUFFLEUPAGUS_G(config).L); 161#define FREE_LST(L) sp_list_free(snuffleupagus_globals->config.L, sp_free_zstr);
162 FREE_LST(config_eval->blacklist); 162 FREE_LST(config_eval->blacklist);
163 FREE_LST(config_eval->whitelist); 163 FREE_LST(config_eval->whitelist);
164 FREE_LST(config_wrapper->whitelist); 164 FREE_LST(config_wrapper->whitelist);
165#undef FREE_LST 165#undef FREE_LST
166 166
167#define FREE_CFG(C) pefree(SNUFFLEUPAGUS_G(config).C, 1); 167#define FREE_CFG(C) pefree(snuffleupagus_globals->config.C, 1);
168 FREE_CFG(config_unserialize); 168#define FREE_CFG_ZSTR(C) sp_free_zstr(snuffleupagus_globals->config.C);
169 FREE_CFG(config_random); 169 FREE_CFG(config_random);
170 FREE_CFG(config_sloppy);
171 FREE_CFG_ZSTR(config_unserialize->dump);
172 FREE_CFG_ZSTR(config_unserialize->textual_representation);
173 FREE_CFG(config_unserialize);
170 FREE_CFG(config_readonly_exec); 174 FREE_CFG(config_readonly_exec);
171 FREE_CFG(config_global_strict); 175 FREE_CFG_ZSTR(config_upload_validation->script);
172 FREE_CFG(config_auto_cookie_secure); 176 FREE_CFG(config_upload_validation);
177 FREE_CFG(config_cookie);
173 FREE_CFG(config_snuffleupagus); 178 FREE_CFG(config_snuffleupagus);
179 FREE_CFG(config_auto_cookie_secure);
180 FREE_CFG(config_global_strict);
174 FREE_CFG(config_disable_xxe); 181 FREE_CFG(config_disable_xxe);
175 FREE_CFG(config_upload_validation); 182 FREE_CFG_ZSTR(config_eval->dump);
183 FREE_CFG_ZSTR(config_eval->textual_representation);
184 FREE_CFG(config_eval);
185 FREE_CFG(config_wrapper);
176 FREE_CFG(config_session); 186 FREE_CFG(config_session);
177 FREE_CFG(config_disabled_functions_reg); 187 FREE_CFG(config_disabled_functions_reg);
178 FREE_CFG(config_disabled_functions_reg_ret); 188 FREE_CFG(config_disabled_functions_reg_ret);
179 FREE_CFG(config_cookie);
180 FREE_CFG(config_wrapper);
181#undef FREE_CFG 189#undef FREE_CFG
182 190#undef FREE_CFG_ZSTR
183 UNREGISTER_INI_ENTRIES();
184
185 return SUCCESS;
186} 191}
187 192
188PHP_RINIT_FUNCTION(snuffleupagus) { 193PHP_RINIT_FUNCTION(snuffleupagus) {
@@ -358,7 +363,7 @@ zend_module_entry snuffleupagus_module_entry = {
358 PHP_SNUFFLEUPAGUS_VERSION, 363 PHP_SNUFFLEUPAGUS_VERSION,
359 PHP_MODULE_GLOBALS(snuffleupagus), 364 PHP_MODULE_GLOBALS(snuffleupagus),
360 PHP_GINIT(snuffleupagus), 365 PHP_GINIT(snuffleupagus),
361 NULL, 366 PHP_GSHUTDOWN(snuffleupagus),
362 NULL, 367 NULL,
363 STANDARD_MODULE_PROPERTIES_EX}; 368 STANDARD_MODULE_PROPERTIES_EX};
364 369
diff --git a/src/sp_config.c b/src/sp_config.c
index c12b435..72781c6 100644
--- a/src/sp_config.c
+++ b/src/sp_config.c
@@ -216,36 +216,52 @@ int sp_parse_config(const char *conf_file) {
216 return SUCCESS; 216 return SUCCESS;
217} 217}
218 218
219void sp_disabled_function_list_free(sp_list_node *list) { 219void sp_free_disabled_function(void *data) {
220 sp_list_node *cursor = list; 220 sp_disabled_function *df = data;
221 while (cursor) {
222 sp_disabled_function *df = cursor->data;
223 if (df) {
224 sp_list_free(df->functions_list);
225 sp_list_free(df->param_array_keys);
226 sp_list_free(df->var_array_keys);
227 221
228 sp_pcre_free(df->r_filename); 222 sp_free_zstr(df->textual_representation);
229 sp_pcre_free(df->r_function);
230 sp_pcre_free(df->r_param);
231 sp_pcre_free(df->r_ret);
232 sp_pcre_free(df->r_value);
233 sp_pcre_free(df->r_key);
234 223
235 sp_tree_free(df->param); 224 sp_free_zstr(df->filename);
236 sp_tree_free(df->var); 225 sp_pcre_free(df->r_filename);
237 } 226
238 cursor = cursor->next; 227 sp_free_zstr(df->function);
239 } 228 sp_pcre_free(df->r_function);
229 sp_list_free(df->functions_list, free);
230
231 sp_free_zstr(df->hash);
232
233 sp_tree_free(df->param);
234 sp_pcre_free(df->r_param);
235
236 sp_pcre_free(df->r_ret);
237 sp_free_zstr(df->ret);
238
239 sp_pcre_free(df->r_value);
240 sp_free_zstr(df->value);
241
242 sp_pcre_free(df->r_key);
243 sp_free_zstr(df->key);
244
245 sp_free_zstr(df->dump);
246 sp_free_zstr(df->alias);
247
248 // sp_list_free(df->param_array_keys);
249 // sp_list_free(df->var_array_keys);
250
251 sp_tree_free(df->var);
252
253 pefree(df->cidr, 1);
240} 254}
241 255
242void sp_cookie_list_free(sp_list_node *list) { 256void sp_free_cookie(void *data) {
243 sp_list_node *cursor = list; 257 sp_cookie *c = data;
244 while (cursor) { 258 if (c->name)
245 sp_cookie *c = cursor->data; 259 zend_string_release_ex(c->name, 1);
246 if (c) { 260 sp_pcre_free(c->name_r);
247 sp_pcre_free(c->name_r); 261}
248 } 262
249 cursor = cursor->next; 263void sp_free_zstr(void *data) {
264 if (data) {
265 zend_string_release_ex((zend_string*)data, 1);
250 } 266 }
251} 267}
diff --git a/src/sp_config.h b/src/sp_config.h
index e7b1473..f3b64a6 100644
--- a/src/sp_config.h
+++ b/src/sp_config.h
@@ -130,8 +130,8 @@ typedef struct {
130 zend_string *alias; 130 zend_string *alias;
131 bool param_is_array; 131 bool param_is_array;
132 bool var_is_array; 132 bool var_is_array;
133 sp_list_node *param_array_keys; 133 // sp_list_node *param_array_keys;
134 sp_list_node *var_array_keys; 134 // sp_list_node *var_array_keys;
135 135
136 bool allow; 136 bool allow;
137 137
@@ -281,7 +281,9 @@ int parse_php_type(char *restrict, char *restrict, void *);
281int parse_list(char *restrict, char *restrict, void *); 281int parse_list(char *restrict, char *restrict, void *);
282 282
283// cleanup 283// cleanup
284void sp_disabled_function_list_free(sp_list_node *); 284void sp_free_disabled_function(void *data);
285void sp_cookie_list_free(sp_list_node *); 285void sp_free_cookie(void *data);
286void sp_free_zstr(void *data);
287
286 288
287#endif /* SP_CONFIG_H */ 289#endif /* SP_CONFIG_H */
diff --git a/src/sp_list.c b/src/sp_list.c
index 0f00371..92e628d 100644
--- a/src/sp_list.c
+++ b/src/sp_list.c
@@ -1,8 +1,22 @@
1#include "php_snuffleupagus.h" 1#include "php_snuffleupagus.h"
2 2
3void sp_list_free(sp_list_node *node) { 3void sp_list_free(sp_list_node *node, void (*free_data_func)(void *data)) {
4 while (node) { 4 while (node) {
5 sp_list_node *tmp = node->next; 5 sp_list_node *tmp = node->next;
6 if (free_data_func && node->data) {
7 free_data_func(node->data);
8 }
9 pefree(node, 1);
10 node = tmp;
11 }
12}
13
14void sp_list_free2(sp_list_node *node) {
15 while (node) {
16 sp_list_node *tmp = node->next;
17 if (node->data) {
18 pefree(node->data, 1);
19 }
6 pefree(node, 1); 20 pefree(node, 1);
7 node = tmp; 21 node = tmp;
8 } 22 }
diff --git a/src/sp_list.h b/src/sp_list.h
index 2c91995..7ceee50 100644
--- a/src/sp_list.h
+++ b/src/sp_list.h
@@ -11,6 +11,7 @@ sp_list_node *sp_list_sort(sp_list_node *, int (*)(sp_list_node const *const,
11 sp_list_node const *const)); 11 sp_list_node const *const));
12sp_list_node *sp_list_insert(sp_list_node *, void *); 12sp_list_node *sp_list_insert(sp_list_node *, void *);
13sp_list_node *sp_list_prepend(sp_list_node *, void *); 13sp_list_node *sp_list_prepend(sp_list_node *, void *);
14void sp_list_free(sp_list_node *); 14void sp_list_free(sp_list_node *, void (*free_data_func)(void *data));
15void sp_list_free2(sp_list_node *node);
15 16
16#endif 17#endif
diff --git a/src/sp_var_parser.c b/src/sp_var_parser.c
index bb5a5c0..eb57f70 100644
--- a/src/sp_var_parser.c
+++ b/src/sp_var_parser.c
@@ -249,7 +249,7 @@ sp_tree *sp_parse_var(const char *line) {
249 } 249 }
250 tokens_list = sp_list_sort(tokens_list, cmp_tokens); 250 tokens_list = sp_list_sort(tokens_list, cmp_tokens);
251 tree = parse_tokens(line, tokens_list); 251 tree = parse_tokens(line, tokens_list);
252 sp_list_free(tokens_list); 252 sp_list_free2(tokens_list);
253 // Check if tree is empty. 253 // Check if tree is empty.
254 if (tree && tree->next == NULL && tree->type == UNDEFINED) { 254 if (tree && tree->next == NULL && tree->type == UNDEFINED) {
255 tree->type = CONSTANT; 255 tree->type = CONSTANT;