summaryrefslogtreecommitdiff
path: root/execute_ih.c
diff options
context:
space:
mode:
authorBen Fuhrmannek2016-02-24 23:33:34 +0100
committerBen Fuhrmannek2016-02-24 23:33:34 +0100
commitd4e9bb339360cb7d6ece5b1b60c08c8611bac19c (patch)
treeceb428cd6745b4363b25144f67304b7fbea212e2 /execute_ih.c
parent346455c6b5716c8ce095235428614e15c0adf13e (diff)
executor improvements
Diffstat (limited to 'execute_ih.c')
-rw-r--r--execute_ih.c495
1 files changed, 495 insertions, 0 deletions
diff --git a/execute_ih.c b/execute_ih.c
new file mode 100644
index 0000000..fa511b9
--- /dev/null
+++ b/execute_ih.c
@@ -0,0 +1,495 @@
1#include "php.h"
2#include "php_suhosin7.h"
3#include "execute.h"
4
5// #ifdef SUHOSIN7_PREG_REPLACE_NULL
6// preg_replace \0 protection may be redundant, because PHP already checks for \0
7S7_IH_FUNCTION(preg_replace)
8{
9 zval *regex, *replace, *subject, *zcount = NULL;
10 zend_long limit = -1;
11 // int replace_count;
12
13#ifndef FAST_ZPP
14 /* Get function parameters and do error-checking. */
15 if (zend_parse_parameters(ZEND_NUM_ARGS(), "zzz|lz/", &regex, &replace, &subject, &limit, &zcount) == FAILURE) {
16 return FAILURE;
17 }
18#else
19 ZEND_PARSE_PARAMETERS_START(3, 5)
20 Z_PARAM_ZVAL(regex)
21 Z_PARAM_ZVAL(replace)
22 Z_PARAM_ZVAL(subject)
23 Z_PARAM_OPTIONAL
24 Z_PARAM_LONG(limit)
25 Z_PARAM_ZVAL_EX(zcount, 0, 1)
26 ZEND_PARSE_PARAMETERS_END_EX(return FAILURE);
27#endif
28
29 if (Z_TYPE_P(regex) != IS_ARRAY) {
30 convert_to_string_ex(regex);
31 // regex is string
32
33 if (strlen(Z_STRVAL_P(regex)) != Z_STRLEN_P(regex)) {
34 suhosin_log(S_EXECUTOR, "string termination attack on first preg_replace parameter detected");
35 if (!SUHOSIN7_G(simulation)) {
36 RETVAL_NULL();
37 return FAILURE;
38 }
39 }
40 } else {
41 // regex is array
42
43 /* For each entry in the regex array, get the entry */
44 zval *regex_entry;
45 ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(regex), regex_entry) {
46 /* Make sure we're dealing with strings. */
47 zend_string *regex_str = zval_get_string(regex_entry);
48
49 if (strlen(ZSTR_VAL(regex_str)) != ZSTR_LEN(regex_str)) {
50 suhosin_log(S_EXECUTOR, "string termination attack on first preg_replace parameter detected");
51 if (!SUHOSIN7_G(simulation)) {
52 RETVAL_NULL();
53 zend_string_release(regex_str);
54 return FAILURE;
55 }
56 }
57
58 zend_string_release(regex_str);
59 } ZEND_HASH_FOREACH_END();
60
61 }
62
63 return SUCCESS;
64}
65
66// #endif /* SUHOSIN7_PREG_REPLACE_NULL */
67
68
69// int ih_symlink(IH_HANDLER_PARAMS)
70// {
71// if (SUHOSIN7_G(executor_allow_symlink)) {
72// return (0);
73// }
74//
75// if (PG(open_basedir) && PG(open_basedir)[0]) {
76// suhosin_log(S_EXECUTOR, "symlink called during open_basedir");
77// if (!SUHOSIN7_G(simulation)) {
78// RETVAL_FALSE;
79// return (1);
80// }
81// }
82//
83// return (0);
84// }
85
86// int ih_mail(IH_HANDLER_PARAMS)
87// {
88// char *to=NULL, *message=NULL, *headers=NULL;
89// char *subject=NULL, *extra_cmd=NULL;
90// char *tmp;
91// int to_len, message_len, headers_len;
92// int subject_len, extra_cmd_len;
93//
94// if (SUHOSIN7_G(mailprotect) == 0) {
95// return (0);
96// }
97//
98// if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|ss",
99// &to, &to_len,
100// &subject, &subject_len,
101// &message, &message_len,
102// &headers, &headers_len,
103// &extra_cmd, &extra_cmd_len
104// ) == FAILURE) {
105// RETVAL_FALSE;
106// return (1);
107// }
108//
109// if (headers_len > 0 && headers &&
110// (strstr(headers, "\n\n") || strstr(headers, "\n\r\n") /* double newline */
111// || *headers == '\n' || (headers[0] == '\r' && headers[1] == '\n') /* starts with newline */
112// )) {
113// suhosin_log(S_MAIL, "mail() - double newline in headers, possible injection, mail dropped");
114// if (!SUHOSIN7_G(simulation)) {
115// RETVAL_FALSE;
116// return (1);
117// }
118// }
119//
120// /* check for spam attempts with buggy webforms */
121// if (to_len > 0 && to) {
122// do {
123// if ((tmp = strchr(to, '\n')) == NULL)
124// tmp = strchr(to, '\r');
125// if (tmp == NULL) break;
126// to = tmp + 1;
127// if (!isspace(*to)) break;
128// } while (1);
129// if (tmp != NULL) {
130// suhosin_log(S_MAIL, "mail() - newline in To header, possible injection, mail dropped");
131// if (!SUHOSIN7_G(simulation)) {
132// RETVAL_FALSE;
133// return (1);
134// }
135// }
136// }
137//
138// if (subject_len > 0 && subject) {
139// do {
140// if ((tmp = strchr(subject, '\n')) == NULL)
141// tmp = strchr(subject, '\r');
142// if (tmp == NULL) break;
143// subject = tmp + 1;
144// if (!isspace(*subject)) break;
145// } while (1);
146// if (tmp != NULL) {
147// suhosin_log(S_MAIL, "mail() - newline in Subject header, possible injection, mail dropped");
148// if (!SUHOSIN7_G(simulation)) {
149// RETVAL_FALSE;
150// return (1);
151// }
152// }
153// }
154//
155// if (SUHOSIN7_G(mailprotect) > 1) {
156// /* search for to, cc or bcc headers */
157// if (headers_len > 0 && headers != NULL) {
158// if (strncasecmp(headers, "to:", sizeof("to:") - 1) == 0 || suhosin_strcasestr(headers, "\nto:")) {
159// suhosin_log(S_MAIL, "mail() - To: headers aren't allowed in the headers parameter.");
160// if (!SUHOSIN7_G(simulation)) {
161// RETVAL_FALSE;
162// return (1);
163// }
164// }
165//
166// if (strncasecmp(headers, "cc:", sizeof("cc:") - 1) == 0 || suhosin_strcasestr(headers, "\ncc:")) {
167// suhosin_log(S_MAIL, "mail() - CC: headers aren't allowed in the headers parameter.");
168// if (!SUHOSIN7_G(simulation)) {
169// RETVAL_FALSE;
170// return (1);
171// }
172// }
173//
174// if (strncasecmp(headers, "bcc:", sizeof("bcc:") - 1) == 0 || suhosin_strcasestr(headers, "\nbcc:")) {
175// suhosin_log(S_MAIL, "mail() - BCC: headers aren't allowed in the headers parameter.");
176// if (!SUHOSIN7_G(simulation)) {
177// RETVAL_FALSE;
178// return (1);
179// }
180// }
181// }
182// }
183//
184// return (0);
185// }
186
187// #define SQLSTATE_SQL 0
188// #define SQLSTATE_IDENTIFIER 1
189// #define SQLSTATE_STRING 2
190// #define SQLSTATE_COMMENT 3
191// #define SQLSTATE_MLCOMMENT 4
192//
193// int ih_querycheck(IH_HANDLER_PARAMS)
194// {
195// void **p = zend_vm_stack_top() - 1;
196// unsigned long arg_count;
197// zval **arg;
198// char *query, *s, *e;
199// zval *backup;
200// int len;
201// char quote;
202// int state = SQLSTATE_SQL;
203// int cnt_union = 0, cnt_select = 0, cnt_comment = 0, cnt_opencomment = 0;
204// int mysql_extension = 0;
205//
206//
207// SDEBUG("function: %s", ih->name);
208// arg_count = (unsigned long) *p;
209//
210// if (ht < (long) ih->arg1) {
211// return (0);
212// }
213//
214// if ((long) ih->arg2) {
215// mysql_extension = 1;
216// }
217//
218// arg = (zval **) p - (arg_count - (long) ih->arg1 + 1); /* count from 0 */
219//
220// backup = *arg;
221// if (Z_TYPE_P(backup) != IS_STRING) {
222// return (0);
223// }
224// len = Z_STRLEN_P(backup);
225// query = Z_STRVAL_P(backup);
226// SDEBUG("SQL |%s|", query);
227//
228// s = query;
229// e = s+len;
230//
231// while (s < e) {
232// switch (state)
233// {
234// case SQLSTATE_SQL:
235// switch (s[0])
236// {
237// case '`':
238// state = SQLSTATE_IDENTIFIER;
239// quote = '`';
240// break;
241// case '\'':
242// case '"':
243// state = SQLSTATE_STRING;
244// quote = *s;
245// break;
246// case '/':
247// if (s[1]=='*') {
248// if (mysql_extension == 1 && s[2] == '!') {
249// s += 2;
250// break;
251// }
252// s++;
253// state = SQLSTATE_MLCOMMENT;
254// cnt_comment++;
255// }
256// break;
257// case '-':
258// if (s[1]=='-') {
259// s++;
260// state = SQLSTATE_COMMENT;
261// cnt_comment++;
262// }
263// break;
264// case '#':
265// state = SQLSTATE_COMMENT;
266// cnt_comment++;
267// break;
268// case 'u':
269// case 'U':
270// if (strncasecmp("union", s, 5)==0) {
271// s += 4;
272// cnt_union++;
273// }
274// break;
275// case 's':
276// case 'S':
277// if (strncasecmp("select", s, 6)==0) {
278// s += 5;
279// cnt_select++;
280// }
281// break;
282// }
283// break;
284// case SQLSTATE_STRING:
285// case SQLSTATE_IDENTIFIER:
286// if (s[0] == quote) {
287// if (s[1] == quote) {
288// s++;
289// } else {
290// state = SQLSTATE_SQL;
291// }
292// }
293// if (s[0] == '\\') {
294// s++;
295// }
296// break;
297// case SQLSTATE_COMMENT:
298// while (s[0] && s[0] != '\n') {
299// s++;
300// }
301// state = SQLSTATE_SQL;
302// break;
303// case SQLSTATE_MLCOMMENT:
304// while (s[0] && (s[0] != '*' || s[1] != '/')) {
305// s++;
306// }
307// if (s[0]) {
308// state = SQLSTATE_SQL;
309// }
310// break;
311// }
312// s++;
313// }
314// if (state == SQLSTATE_MLCOMMENT) {
315// cnt_opencomment = 1;
316// }
317//
318// if (cnt_opencomment && SUHOSIN7_G(sql_opencomment)>0) {
319// suhosin_log(S_SQL, "Open comment in SQL query: '%*s'", len, query);
320// if (SUHOSIN7_G(sql_opencomment)>1) {
321// suhosin_bailout();
322// }
323// }
324//
325// if (cnt_comment && SUHOSIN7_G(sql_comment)>0) {
326// suhosin_log(S_SQL, "Comment in SQL query: '%*s'", len, query);
327// if (SUHOSIN7_G(sql_comment)>1) {
328// suhosin_bailout();
329// }
330// }
331//
332// if (cnt_union && SUHOSIN7_G(sql_union)>0) {
333// suhosin_log(S_SQL, "UNION in SQL query: '%*s'", len, query);
334// if (SUHOSIN7_G(sql_union)>1) {
335// suhosin_bailout();
336// }
337// }
338//
339// if (cnt_select>1 && SUHOSIN7_G(sql_mselect)>0) {
340// suhosin_log(S_SQL, "Multiple SELECT in SQL query: '%*s'", len, query);
341// if (SUHOSIN7_G(sql_mselect)>1) {
342// suhosin_bailout();
343// }
344// }
345//
346// return (0);
347// }
348//
349//
350// int ih_fixusername(IH_HANDLER_PARAMS)
351// {
352// void **p = zend_vm_stack_top() - 1;
353// unsigned long arg_count;
354// zval **arg;
355// char *prefix, *postfix, *user, *user_match, *cp;
356// zval *backup, *my_user;
357// int prefix_len, postfix_len, len;
358//
359// SDEBUG("function (fixusername): %s", ih->name);
360//
361// prefix = SUHOSIN7_G(sql_user_prefix);
362// postfix = SUHOSIN7_G(sql_user_postfix);
363// user_match = SUHOSIN7_G(sql_user_match);
364//
365// arg_count = (unsigned long) *p;
366//
367// if (ht < (long) ih->arg1) {
368// return (0);
369// }
370//
371// arg = (zval **) p - (arg_count - (long) ih->arg1 + 1); /* count from 0 */
372//
373// backup = *arg;
374// if (Z_TYPE_P(backup) != IS_STRING) {
375// user = "";
376// len = 0;
377// } else {
378// len = Z_STRLEN_P(backup);
379// user = Z_STRVAL_P(backup);
380// }
381//
382// cp = user;
383// while (cp < user+len) {
384// if (*cp < 32) {
385// suhosin_log(S_SQL, "SQL username contains invalid characters");
386// if (!SUHOSIN7_G(simulation)) {
387// RETVAL_FALSE;
388// return (1);
389// }
390// break;
391// }
392// cp++;
393// }
394//
395// if ((prefix != NULL && prefix[0]) || (postfix != NULL && postfix[0])) {
396// if (prefix == NULL) {
397// prefix = "";
398// }
399// if (postfix == NULL) {
400// postfix = "";
401// }
402// prefix_len = strlen(prefix);
403// postfix_len = strlen(postfix);
404//
405// MAKE_STD_ZVAL(my_user);
406// my_user->type = IS_STRING;
407// my_user->value.str.len = spprintf(&my_user->value.str.val, 0, "%s%s%s", prefix, user, postfix);
408//
409// /* XXX: memory_leak? */
410// *arg = my_user;
411//
412// len = Z_STRLEN_P(my_user);
413// user = Z_STRVAL_P(my_user);
414// }
415//
416// if (user_match && user_match[0]) {
417// #ifdef HAVE_FNMATCH
418// if (fnmatch(user_match, user, 0) != 0) {
419// suhosin_log(S_SQL, "SQL username ('%s') does not match suhosin.sql.user_match ('%s')", user, user_match);
420// if (!SUHOSIN7_G(simulation)) {
421// RETVAL_FALSE;
422// return (1);
423// }
424// }
425// #else
426// #warning no support for fnmatch() - setting suhosin.sql.user_match will always fail.
427// suhosin_log(S_SQL, "suhosin.sql.user_match specified, but system does not support fnmatch()");
428// if (!SUHOSIN7_G(simulation)) {
429// RETVAL_FALSE;
430// return (1);
431// }
432// #endif
433// }
434//
435// SDEBUG("function: %s - user: %s", ih->name, user);
436//
437// return (0);
438// }
439//
440//
441// static int ih_function_exists(IH_HANDLER_PARAMS)
442// {
443// zval **function_name;
444// zend_function *func;
445// char *lcname;
446// zend_bool retval;
447// int func_name_len;
448//
449// if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &function_name)==FAILURE) {
450// ZEND_WRONG_PARAM_COUNT_WITH_RETVAL(1);
451// }
452// convert_to_string_ex(function_name);
453// func_name_len = Z_STRLEN_PP(function_name);
454// lcname = estrndup(Z_STRVAL_PP(function_name), func_name_len);
455// zend_str_tolower(lcname, func_name_len);
456//
457// retval = (zend_hash_find(EG(function_table), lcname, func_name_len+1, (void **)&func) == SUCCESS);
458//
459// /*
460// * A bit of a hack, but not a bad one: we see if the handler of the function
461// * is actually one that displays "function is disabled" message.
462// */
463// if (retval && func->type == ZEND_INTERNAL_FUNCTION &&
464// func->internal_function.handler == zif_display_disabled_function) {
465// retval = 0;
466// }
467//
468// /* Now check if function is forbidden by Suhosin */
469// if (SUHOSIN7_G(in_code_type) == SUHOSIN_EVAL) {
470// if (SUHOSIN7_G(eval_whitelist) != NULL) {
471// if (!zend_hash_exists(SUHOSIN7_G(eval_whitelist), lcname, func_name_len+1)) {
472// retval = 0;
473// }
474// } else if (SUHOSIN7_G(eval_blacklist) != NULL) {
475// if (zend_hash_exists(SUHOSIN7_G(eval_blacklist), lcname, func_name_len+1)) {
476// retval = 0;
477// }
478// }
479// }
480//
481// if (SUHOSIN7_G(func_whitelist) != NULL) {
482// if (!zend_hash_exists(SUHOSIN7_G(func_whitelist), lcname, func_name_len+1)) {
483// retval = 0;
484// }
485// } else if (SUHOSIN7_G(func_blacklist) != NULL) {
486// if (zend_hash_exists(SUHOSIN7_G(func_blacklist), lcname, func_name_len+1)) {
487// retval = 0;
488// }
489// }
490//
491// efree(lcname);
492//
493// RETVAL_BOOL(retval);
494// return (1);
495// }