summaryrefslogtreecommitdiff
path: root/execute.c
diff options
context:
space:
mode:
Diffstat (limited to 'execute.c')
-rw-r--r--execute.c700
1 files changed, 123 insertions, 577 deletions
diff --git a/execute.c b/execute.c
index 0e569e0..4a6e279 100644
--- a/execute.c
+++ b/execute.c
@@ -23,29 +23,30 @@
23#include "config.h" 23#include "config.h"
24#endif 24#endif
25 25
26#include <fcntl.h> 26// #include <fcntl.h>
27#include "php.h" 27#include "php.h"
28#include "php_ini.h" 28// #include "php_ini.h"
29#include "zend_hash.h" 29// #include "zend_hash.h"
30#include "zend_extensions.h" 30#include "zend_extensions.h"
31#include "ext/standard/info.h" 31// #include "ext/standard/info.h"
32#include "ext/standard/php_rand.h" 32// #include "ext/standard/php_rand.h"
33#include "ext/standard/php_lcg.h" 33// #include "ext/standard/php_lcg.h"
34#include "php_suhosin7.h" 34#include "php_suhosin7.h"
35#include "zend_compile.h" 35// #include "zend_compile.h"
36#include "zend_llist.h" 36// #include "zend_llist.h"
37#include "SAPI.h" 37#include "SAPI.h"
38#include "execute.h"
38 39
39#include "sha256.h" 40// #include "sha256.h"
40 41
41#ifdef PHP_WIN32 42#ifdef PHP_WIN32
42# include "win32/fnmatch.h" 43// # include "win32/fnmatch.h"
43# include "win32/winutil.h" 44# include "win32/winutil.h"
44# include "win32/time.h" 45# include "win32/time.h"
45#else 46#else
46# ifdef HAVE_FNMATCH 47// # ifdef HAVE_FNMATCH
47# include <fnmatch.h> 48// # include <fnmatch.h>
48# endif 49// # endif
49# include <sys/time.h> 50# include <sys/time.h>
50#endif 51#endif
51 52
@@ -86,7 +87,7 @@ conts:
86#define SUHOSIN_CODE_TYPE_UNKNOWN 0 87#define SUHOSIN_CODE_TYPE_UNKNOWN 0
87#define SUHOSIN_CODE_TYPE_COMMANDLINE 1 88#define SUHOSIN_CODE_TYPE_COMMANDLINE 1
88#define SUHOSIN_CODE_TYPE_EVAL 2 89#define SUHOSIN_CODE_TYPE_EVAL 2
89#define SUHOSIN_CODE_TYPE_REGEXP 3 90// #define SUHOSIN_CODE_TYPE_REGEXP 3
90#define SUHOSIN_CODE_TYPE_ASSERT 4 91#define SUHOSIN_CODE_TYPE_ASSERT 4
91#define SUHOSIN_CODE_TYPE_CFUNC 5 92#define SUHOSIN_CODE_TYPE_CFUNC 5
92#define SUHOSIN_CODE_TYPE_SUHOSIN 6 93#define SUHOSIN_CODE_TYPE_SUHOSIN 6
@@ -98,7 +99,7 @@ conts:
98#define SUHOSIN_CODE_TYPE_BADFILE 12 99#define SUHOSIN_CODE_TYPE_BADFILE 12
99#define SUHOSIN_CODE_TYPE_LONGNAME 13 100#define SUHOSIN_CODE_TYPE_LONGNAME 13
100#define SUHOSIN_CODE_TYPE_MANYDOTS 14 101#define SUHOSIN_CODE_TYPE_MANYDOTS 14
101#define SUHOSIN_CODE_TYPE_WRITABLE 15 102#define SUHOSIN_CODE_TYPE_WRITABLE 15
102#define SUHOSIN_CODE_TYPE_MBREGEXP 16 103#define SUHOSIN_CODE_TYPE_MBREGEXP 16
103 104
104static int suhosin_check_filename(char *s, int len) 105static int suhosin_check_filename(char *s, int len)
@@ -315,9 +316,9 @@ static int suhosin_detect_codetype(zend_op_array *op_array)
315 return SUHOSIN_CODE_TYPE_EVAL; 316 return SUHOSIN_CODE_TYPE_EVAL;
316 } 317 }
317 318
318 if (strstr(s, "regexp code") != NULL) { 319 // if (strstr(s, "regexp code") != NULL) {
319 return SUHOSIN_CODE_TYPE_REGEXP; 320 // return SUHOSIN_CODE_TYPE_REGEXP;
320 } 321 // }
321 322
322 if (strstr(s, "mbregex replace") != NULL) { 323 if (strstr(s, "mbregex replace") != NULL) {
323 return SUHOSIN_CODE_TYPE_MBREGEXP; 324 return SUHOSIN_CODE_TYPE_MBREGEXP;
@@ -519,18 +520,23 @@ not_evaled_code:
519 } 520 }
520 break; 521 break;
521 522
522 case SUHOSIN_CODE_TYPE_REGEXP: 523 // case SUHOSIN_CODE_TYPE_REGEXP:
524 // if (SUHOSIN7_G(executor_disable_emod)) {
525 // suhosin_log(S_EXECUTOR|S_GETCALLER, "use of preg_replace() with /e modifier is forbidden by configuration");
526 // if (!SUHOSIN7_G(simulation)) {
527 // zend_error(E_ERROR, "SUHOSIN - Use of preg_replace() with /e modifier is forbidden by configuration");
528 // }
529 // }
530 // break;
531
532 case SUHOSIN_CODE_TYPE_MBREGEXP:
523 if (SUHOSIN7_G(executor_disable_emod)) { 533 if (SUHOSIN7_G(executor_disable_emod)) {
524 suhosin_log(S_EXECUTOR|S_GETCALLER, "use of preg_replace() with /e modifier is forbidden by configuration"); 534 suhosin_log(S_EXECUTOR|S_GETCALLER, "use of /e modifier in replace function is forbidden by configuration");
525 if (!SUHOSIN7_G(simulation)) { 535 if (!SUHOSIN7_G(simulation)) {
526 zend_error(E_ERROR, "SUHOSIN - Use of preg_replace() with /e modifier is forbidden by configuration"); 536 zend_error(E_ERROR, "SUHOSIN - Use of /e modifier in replace function is forbidden by configuration");
527 } 537 }
528 } 538 }
529 break; 539 break;
530
531 case SUHOSIN_CODE_TYPE_MBREGEXP:
532 /* XXX TODO: Do we want to disallow this, too? */
533 break;
534 540
535 case SUHOSIN_CODE_TYPE_ASSERT: 541 case SUHOSIN_CODE_TYPE_ASSERT:
536 break; 542 break;
@@ -603,499 +609,16 @@ continue_execution:
603/* }}} */ 609/* }}} */
604 610
605 611
606#define IH_HANDLER_PARAMS_REST int ht, zval *return_value
607#define IH_HANDLER_PARAMS internal_function_handler *ih, IH_HANDLER_PARAMS_REST
608#define IH_HANDLER_PARAM_PASSTHRU ih, ht, return_value
609
610
611HashTable ihandler_table;
612 612
613typedef struct _internal_function_handler { 613// ----------------------------------------------------------------------------
614 614
615 char *name; 615static HashTable ihandler_table;
616 int (*handler)(struct _internal_function_handler *ih, IH_HANDLER_PARAMS_REST);
617 void *arg1;
618 void *arg2;
619 void *arg3;
620 616
621} internal_function_handler;
622
623// int ih_preg_replace(IH_HANDLER_PARAMS)
624// {
625// zval **regex,
626// **replace,
627// **subject,
628// **limit, **zcount;
629//
630// if (zend_parse_parameters(ZEND_NUM_ARGS(), "ZZZ|ZZ", &regex, &replace, &subject, &limit, &zcount) == FAILURE) {
631// return(0);
632// }
633//
634// if (Z_TYPE_PP(regex) == IS_ARRAY) {
635// zval **regex_entry;
636//
637// zend_hash_internal_pointer_reset(Z_ARRVAL_PP(regex));
638// /* For each entry in the regex array, get the entry */
639// while (zend_hash_get_current_data(Z_ARRVAL_PP(regex), (void **)&regex_entry) == SUCCESS) {
640//
641// if (Z_TYPE_PP(regex_entry) == IS_STRING) {
642// if (strlen(Z_STRVAL_PP(regex_entry)) != Z_STRLEN_PP(regex_entry)) {
643// suhosin_log(S_EXECUTOR, "string termination attack on first preg_replace parameter detected");
644// if (!SUHOSIN7_G(simulation)) {
645// RETVAL_FALSE;
646// return (1);
647// }
648// }
649// }
650//
651// zend_hash_move_forward(Z_ARRVAL_PP(regex));
652//
653// }
654//
655// } else if (Z_TYPE_PP(regex) == IS_STRING) {
656// if (strlen(Z_STRVAL_PP(regex)) != Z_STRLEN_PP(regex)) {
657// suhosin_log(S_EXECUTOR, "string termination attack on first preg_replace parameter detected");
658// if (!SUHOSIN7_G(simulation)) {
659// RETVAL_FALSE;
660// return (1);
661// }
662// }
663// }
664//
665// return (0);
666// }
667 617
668// int ih_symlink(IH_HANDLER_PARAMS)
669// {
670// if (SUHOSIN7_G(executor_allow_symlink)) {
671// return (0);
672// }
673//
674// if (PG(open_basedir) && PG(open_basedir)[0]) {
675// suhosin_log(S_EXECUTOR, "symlink called during open_basedir");
676// if (!SUHOSIN7_G(simulation)) {
677// RETVAL_FALSE;
678// return (1);
679// }
680// }
681//
682// return (0);
683// }
684 618
685// int ih_mail(IH_HANDLER_PARAMS) 619static suhosin_internal_function_handler ihandlers[] = {
686// { 620 S7_IH_ENTRY0i(preg_replace)
687// char *to=NULL, *message=NULL, *headers=NULL;
688// char *subject=NULL, *extra_cmd=NULL;
689// char *tmp;
690// int to_len, message_len, headers_len;
691// int subject_len, extra_cmd_len;
692//
693// if (SUHOSIN7_G(mailprotect) == 0) {
694// return (0);
695// }
696//
697// if (zend_parse_parameters(ZEND_NUM_ARGS(), "sss|ss",
698// &to, &to_len,
699// &subject, &subject_len,
700// &message, &message_len,
701// &headers, &headers_len,
702// &extra_cmd, &extra_cmd_len
703// ) == FAILURE) {
704// RETVAL_FALSE;
705// return (1);
706// }
707//
708// if (headers_len > 0 && headers &&
709// (strstr(headers, "\n\n") || strstr(headers, "\n\r\n") /* double newline */
710// || *headers == '\n' || (headers[0] == '\r' && headers[1] == '\n') /* starts with newline */
711// )) {
712// suhosin_log(S_MAIL, "mail() - double newline in headers, possible injection, mail dropped");
713// if (!SUHOSIN7_G(simulation)) {
714// RETVAL_FALSE;
715// return (1);
716// }
717// }
718//
719// /* check for spam attempts with buggy webforms */
720// if (to_len > 0 && to) {
721// do {
722// if ((tmp = strchr(to, '\n')) == NULL)
723// tmp = strchr(to, '\r');
724// if (tmp == NULL) break;
725// to = tmp + 1;
726// if (!isspace(*to)) break;
727// } while (1);
728// if (tmp != NULL) {
729// suhosin_log(S_MAIL, "mail() - newline in To header, possible injection, mail dropped");
730// if (!SUHOSIN7_G(simulation)) {
731// RETVAL_FALSE;
732// return (1);
733// }
734// }
735// }
736//
737// if (subject_len > 0 && subject) {
738// do {
739// if ((tmp = strchr(subject, '\n')) == NULL)
740// tmp = strchr(subject, '\r');
741// if (tmp == NULL) break;
742// subject = tmp + 1;
743// if (!isspace(*subject)) break;
744// } while (1);
745// if (tmp != NULL) {
746// suhosin_log(S_MAIL, "mail() - newline in Subject header, possible injection, mail dropped");
747// if (!SUHOSIN7_G(simulation)) {
748// RETVAL_FALSE;
749// return (1);
750// }
751// }
752// }
753//
754// if (SUHOSIN7_G(mailprotect) > 1) {
755// /* search for to, cc or bcc headers */
756// if (headers_len > 0 && headers != NULL) {
757// if (strncasecmp(headers, "to:", sizeof("to:") - 1) == 0 || suhosin_strcasestr(headers, "\nto:")) {
758// suhosin_log(S_MAIL, "mail() - To: headers aren't allowed in the headers parameter.");
759// if (!SUHOSIN7_G(simulation)) {
760// RETVAL_FALSE;
761// return (1);
762// }
763// }
764//
765// if (strncasecmp(headers, "cc:", sizeof("cc:") - 1) == 0 || suhosin_strcasestr(headers, "\ncc:")) {
766// suhosin_log(S_MAIL, "mail() - CC: headers aren't allowed in the headers parameter.");
767// if (!SUHOSIN7_G(simulation)) {
768// RETVAL_FALSE;
769// return (1);
770// }
771// }
772//
773// if (strncasecmp(headers, "bcc:", sizeof("bcc:") - 1) == 0 || suhosin_strcasestr(headers, "\nbcc:")) {
774// suhosin_log(S_MAIL, "mail() - BCC: headers aren't allowed in the headers parameter.");
775// if (!SUHOSIN7_G(simulation)) {
776// RETVAL_FALSE;
777// return (1);
778// }
779// }
780// }
781// }
782//
783// return (0);
784// }
785 621
786// #define SQLSTATE_SQL 0
787// #define SQLSTATE_IDENTIFIER 1
788// #define SQLSTATE_STRING 2
789// #define SQLSTATE_COMMENT 3
790// #define SQLSTATE_MLCOMMENT 4
791//
792// int ih_querycheck(IH_HANDLER_PARAMS)
793// {
794// void **p = zend_vm_stack_top() - 1;
795// unsigned long arg_count;
796// zval **arg;
797// char *query, *s, *e;
798// zval *backup;
799// int len;
800// char quote;
801// int state = SQLSTATE_SQL;
802// int cnt_union = 0, cnt_select = 0, cnt_comment = 0, cnt_opencomment = 0;
803// int mysql_extension = 0;
804//
805//
806// SDEBUG("function: %s", ih->name);
807// arg_count = (unsigned long) *p;
808//
809// if (ht < (long) ih->arg1) {
810// return (0);
811// }
812//
813// if ((long) ih->arg2) {
814// mysql_extension = 1;
815// }
816//
817// arg = (zval **) p - (arg_count - (long) ih->arg1 + 1); /* count from 0 */
818//
819// backup = *arg;
820// if (Z_TYPE_P(backup) != IS_STRING) {
821// return (0);
822// }
823// len = Z_STRLEN_P(backup);
824// query = Z_STRVAL_P(backup);
825// SDEBUG("SQL |%s|", query);
826//
827// s = query;
828// e = s+len;
829//
830// while (s < e) {
831// switch (state)
832// {
833// case SQLSTATE_SQL:
834// switch (s[0])
835// {
836// case '`':
837// state = SQLSTATE_IDENTIFIER;
838// quote = '`';
839// break;
840// case '\'':
841// case '"':
842// state = SQLSTATE_STRING;
843// quote = *s;
844// break;
845// case '/':
846// if (s[1]=='*') {
847// if (mysql_extension == 1 && s[2] == '!') {
848// s += 2;
849// break;
850// }
851// s++;
852// state = SQLSTATE_MLCOMMENT;
853// cnt_comment++;
854// }
855// break;
856// case '-':
857// if (s[1]=='-') {
858// s++;
859// state = SQLSTATE_COMMENT;
860// cnt_comment++;
861// }
862// break;
863// case '#':
864// state = SQLSTATE_COMMENT;
865// cnt_comment++;
866// break;
867// case 'u':
868// case 'U':
869// if (strncasecmp("union", s, 5)==0) {
870// s += 4;
871// cnt_union++;
872// }
873// break;
874// case 's':
875// case 'S':
876// if (strncasecmp("select", s, 6)==0) {
877// s += 5;
878// cnt_select++;
879// }
880// break;
881// }
882// break;
883// case SQLSTATE_STRING:
884// case SQLSTATE_IDENTIFIER:
885// if (s[0] == quote) {
886// if (s[1] == quote) {
887// s++;
888// } else {
889// state = SQLSTATE_SQL;
890// }
891// }
892// if (s[0] == '\\') {
893// s++;
894// }
895// break;
896// case SQLSTATE_COMMENT:
897// while (s[0] && s[0] != '\n') {
898// s++;
899// }
900// state = SQLSTATE_SQL;
901// break;
902// case SQLSTATE_MLCOMMENT:
903// while (s[0] && (s[0] != '*' || s[1] != '/')) {
904// s++;
905// }
906// if (s[0]) {
907// state = SQLSTATE_SQL;
908// }
909// break;
910// }
911// s++;
912// }
913// if (state == SQLSTATE_MLCOMMENT) {
914// cnt_opencomment = 1;
915// }
916//
917// if (cnt_opencomment && SUHOSIN7_G(sql_opencomment)>0) {
918// suhosin_log(S_SQL, "Open comment in SQL query: '%*s'", len, query);
919// if (SUHOSIN7_G(sql_opencomment)>1) {
920// suhosin_bailout();
921// }
922// }
923//
924// if (cnt_comment && SUHOSIN7_G(sql_comment)>0) {
925// suhosin_log(S_SQL, "Comment in SQL query: '%*s'", len, query);
926// if (SUHOSIN7_G(sql_comment)>1) {
927// suhosin_bailout();
928// }
929// }
930//
931// if (cnt_union && SUHOSIN7_G(sql_union)>0) {
932// suhosin_log(S_SQL, "UNION in SQL query: '%*s'", len, query);
933// if (SUHOSIN7_G(sql_union)>1) {
934// suhosin_bailout();
935// }
936// }
937//
938// if (cnt_select>1 && SUHOSIN7_G(sql_mselect)>0) {
939// suhosin_log(S_SQL, "Multiple SELECT in SQL query: '%*s'", len, query);
940// if (SUHOSIN7_G(sql_mselect)>1) {
941// suhosin_bailout();
942// }
943// }
944//
945// return (0);
946// }
947//
948//
949// int ih_fixusername(IH_HANDLER_PARAMS)
950// {
951// void **p = zend_vm_stack_top() - 1;
952// unsigned long arg_count;
953// zval **arg;
954// char *prefix, *postfix, *user, *user_match, *cp;
955// zval *backup, *my_user;
956// int prefix_len, postfix_len, len;
957//
958// SDEBUG("function (fixusername): %s", ih->name);
959//
960// prefix = SUHOSIN7_G(sql_user_prefix);
961// postfix = SUHOSIN7_G(sql_user_postfix);
962// user_match = SUHOSIN7_G(sql_user_match);
963//
964// arg_count = (unsigned long) *p;
965//
966// if (ht < (long) ih->arg1) {
967// return (0);
968// }
969//
970// arg = (zval **) p - (arg_count - (long) ih->arg1 + 1); /* count from 0 */
971//
972// backup = *arg;
973// if (Z_TYPE_P(backup) != IS_STRING) {
974// user = "";
975// len = 0;
976// } else {
977// len = Z_STRLEN_P(backup);
978// user = Z_STRVAL_P(backup);
979// }
980//
981// cp = user;
982// while (cp < user+len) {
983// if (*cp < 32) {
984// suhosin_log(S_SQL, "SQL username contains invalid characters");
985// if (!SUHOSIN7_G(simulation)) {
986// RETVAL_FALSE;
987// return (1);
988// }
989// break;
990// }
991// cp++;
992// }
993//
994// if ((prefix != NULL && prefix[0]) || (postfix != NULL && postfix[0])) {
995// if (prefix == NULL) {
996// prefix = "";
997// }
998// if (postfix == NULL) {
999// postfix = "";
1000// }
1001// prefix_len = strlen(prefix);
1002// postfix_len = strlen(postfix);
1003//
1004// MAKE_STD_ZVAL(my_user);
1005// my_user->type = IS_STRING;
1006// my_user->value.str.len = spprintf(&my_user->value.str.val, 0, "%s%s%s", prefix, user, postfix);
1007//
1008// /* XXX: memory_leak? */
1009// *arg = my_user;
1010//
1011// len = Z_STRLEN_P(my_user);
1012// user = Z_STRVAL_P(my_user);
1013// }
1014//
1015// if (user_match && user_match[0]) {
1016// #ifdef HAVE_FNMATCH
1017// if (fnmatch(user_match, user, 0) != 0) {
1018// suhosin_log(S_SQL, "SQL username ('%s') does not match suhosin.sql.user_match ('%s')", user, user_match);
1019// if (!SUHOSIN7_G(simulation)) {
1020// RETVAL_FALSE;
1021// return (1);
1022// }
1023// }
1024// #else
1025// #warning no support for fnmatch() - setting suhosin.sql.user_match will always fail.
1026// suhosin_log(S_SQL, "suhosin.sql.user_match specified, but system does not support fnmatch()");
1027// if (!SUHOSIN7_G(simulation)) {
1028// RETVAL_FALSE;
1029// return (1);
1030// }
1031// #endif
1032// }
1033//
1034// SDEBUG("function: %s - user: %s", ih->name, user);
1035//
1036// return (0);
1037// }
1038//
1039//
1040// static int ih_function_exists(IH_HANDLER_PARAMS)
1041// {
1042// zval **function_name;
1043// zend_function *func;
1044// char *lcname;
1045// zend_bool retval;
1046// int func_name_len;
1047//
1048// if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &function_name)==FAILURE) {
1049// ZEND_WRONG_PARAM_COUNT_WITH_RETVAL(1);
1050// }
1051// convert_to_string_ex(function_name);
1052// func_name_len = Z_STRLEN_PP(function_name);
1053// lcname = estrndup(Z_STRVAL_PP(function_name), func_name_len);
1054// zend_str_tolower(lcname, func_name_len);
1055//
1056// retval = (zend_hash_find(EG(function_table), lcname, func_name_len+1, (void **)&func) == SUCCESS);
1057//
1058// /*
1059// * A bit of a hack, but not a bad one: we see if the handler of the function
1060// * is actually one that displays "function is disabled" message.
1061// */
1062// if (retval && func->type == ZEND_INTERNAL_FUNCTION &&
1063// func->internal_function.handler == zif_display_disabled_function) {
1064// retval = 0;
1065// }
1066//
1067// /* Now check if function is forbidden by Suhosin */
1068// if (SUHOSIN7_G(in_code_type) == SUHOSIN_EVAL) {
1069// if (SUHOSIN7_G(eval_whitelist) != NULL) {
1070// if (!zend_hash_exists(SUHOSIN7_G(eval_whitelist), lcname, func_name_len+1)) {
1071// retval = 0;
1072// }
1073// } else if (SUHOSIN7_G(eval_blacklist) != NULL) {
1074// if (zend_hash_exists(SUHOSIN7_G(eval_blacklist), lcname, func_name_len+1)) {
1075// retval = 0;
1076// }
1077// }
1078// }
1079//
1080// if (SUHOSIN7_G(func_whitelist) != NULL) {
1081// if (!zend_hash_exists(SUHOSIN7_G(func_whitelist), lcname, func_name_len+1)) {
1082// retval = 0;
1083// }
1084// } else if (SUHOSIN7_G(func_blacklist) != NULL) {
1085// if (zend_hash_exists(SUHOSIN7_G(func_blacklist), lcname, func_name_len+1)) {
1086// retval = 0;
1087// }
1088// }
1089//
1090// efree(lcname);
1091//
1092// RETVAL_BOOL(retval);
1093// return (1);
1094// }
1095
1096// #include "execute_rnd.inc.c"
1097
1098internal_function_handler ihandlers[] = {
1099 // { "preg_replace", ih_preg_replace, NULL, NULL, NULL }, 622 // { "preg_replace", ih_preg_replace, NULL, NULL, NULL },
1100 // { "mail", ih_mail, NULL, NULL, NULL }, 623 // { "mail", ih_mail, NULL, NULL, NULL },
1101 // { "symlink", ih_symlink, NULL, NULL, NULL }, 624 // { "symlink", ih_symlink, NULL, NULL, NULL },
@@ -1139,7 +662,7 @@ internal_function_handler ihandlers[] = {
1139 // { "mysql_db_query", ih_querycheck, (void *)2, (void *)1, NULL }, 662 // { "mysql_db_query", ih_querycheck, (void *)2, (void *)1, NULL },
1140 // { "mysql_unbuffered_query", ih_querycheck, (void *)1, (void *)1, NULL }, 663 // { "mysql_unbuffered_query", ih_querycheck, (void *)1, (void *)1, NULL },
1141 664
1142#ifdef SUHOSIN_EXPERIMENTAL 665#ifdef SUHOSIN7_EXPERIMENTAL
1143 /* MaxDB */ 666 /* MaxDB */
1144 // { "maxdb::maxdb", ih_fixusername, (void *)2, NULL, NULL }, 667 // { "maxdb::maxdb", ih_fixusername, (void *)2, NULL, NULL },
1145 // { "maxdb_connect", ih_fixusername, (void *)2, NULL, NULL }, 668 // { "maxdb_connect", ih_fixusername, (void *)2, NULL, NULL },
@@ -1198,8 +721,8 @@ internal_function_handler ihandlers[] = {
1198 { NULL, NULL, NULL, NULL, NULL } 721 { NULL, NULL, NULL, NULL, NULL }
1199}; 722};
1200 723
1201#define FUNCTION_WARNING() zend_error(E_WARNING, "%s() has been disabled for security reasons", suhosin_get_active_function_name()); 724#define FUNCTION_WARNING(fname) zend_error(E_WARNING, "%s() has been disabled for security reasons", (fname));
1202#define FUNCTION_SIMULATE_WARNING() zend_error(E_WARNING, "SIMULATION - %s() has been disabled for security reasons", suhosin_get_active_function_name()); 725#define FUNCTION_SIMULATE_WARNING(fname) zend_error(E_WARNING, "SIMULATION - %s() has been disabled for security reasons", (fname));
1203 726
1204/* {{{ void suhosin_execute_internal 727/* {{{ void suhosin_execute_internal
1205 * This function provides a hook for internal execution */ 728 * This function provides a hook for internal execution */
@@ -1208,10 +731,28 @@ internal_function_handler ihandlers[] = {
1208 731
1209ZEND_API static void suhosin_execute_internal(zend_execute_data *execute_data, zval *return_value) 732ZEND_API static void suhosin_execute_internal(zend_execute_data *execute_data, zval *return_value)
1210{ 733{
734 if (execute_data == NULL) {
735 // if (EG(current_execute_data) != NULL) {
736 // execute_data = EG(current_execute_data);
737 // }
738 suhosin_log(S_EXECUTOR|S_GETCALLER, "execution without data. something is wrong.");
739 suhosin_bailout();
740 return;
741 }
742
743 zend_function *func = execute_data->func;
744 if (func == NULL) {
745 suhosin_log(S_EXECUTOR|S_GETCALLER, "execution without function context. something is wrong.");
746 suhosin_bailout();
747 }
748
749
1211 // zval *return_value; 750 // zval *return_value;
1212 // zval **return_value_ptr; 751 // zval **return_value_ptr;
1213 // zval *this_ptr; 752 // zval *this_ptr;
1214 int ht = 0; 753 int ht = 0;
754 int retval = SUCCESS;
755
1215 756
1216 // if (fci) { 757 // if (fci) {
1217 // return_value = *fci->retval_ptr_ptr; 758 // return_value = *fci->retval_ptr_ptr;
@@ -1249,32 +790,35 @@ ZEND_API static void suhosin_execute_internal(zend_execute_data *execute_data, z
1249 // zend_str_tolower(lcname, function_name_strlen); 790 // zend_str_tolower(lcname, function_name_strlen);
1250 // } 791 // }
1251 792
1252 // TODO: check execute_data + ->func 793 zend_string *function_name = func->common.function_name;
1253 794 if (function_name == NULL) {
1254 zend_string *function_name = execute_data->func->op_array.function_name; 795 function_name = func->op_array.function_name;
1255 796 }
1256 // TODO: check for function_name == NULL 797 if (function_name == NULL) {
1257 798 // no function name -> skip whitelists/blacklists
1258 SDEBUG("function: %s", ZSTR_VAL(function_name)); 799 goto execute_internal_continue;
800 }
801
802 SDEBUG("function: [%s]/%zu", ZSTR_VAL(function_name), ZSTR_LEN(function_name)) ;
1259 803
1260 if (SUHOSIN7_G(in_code_type) == SUHOSIN_EVAL) { 804 if (SUHOSIN7_G(in_code_type) == SUHOSIN_EVAL) {
1261 805
1262 if (SUHOSIN7_G(eval_whitelist) != NULL) { 806 if (SUHOSIN7_G(eval_whitelist) != NULL) {
1263 if (!zend_hash_exists(SUHOSIN7_G(eval_whitelist), function_name)) { 807 if (!zend_hash_exists(SUHOSIN7_G(eval_whitelist), function_name)) {
1264 suhosin_log(S_EXECUTOR|S_GETCALLER, "function outside of eval whitelist called: %s()", ZSTR_VAL(function_name)); 808 suhosin_log(S_EXECUTOR|S_GETCALLER, "eval'd function not whitelisted: %s()", ZSTR_VAL(function_name));
1265 if (!SUHOSIN7_G(simulation)) { 809 if (!SUHOSIN7_G(simulation)) {
1266 goto execute_internal_bailout; 810 goto execute_internal_bailout;
1267 } else { 811 } else {
1268 FUNCTION_SIMULATE_WARNING() 812 FUNCTION_SIMULATE_WARNING(ZSTR_VAL(function_name))
1269 } 813 }
1270 } 814 }
1271 } else if (SUHOSIN7_G(eval_blacklist) != NULL) { 815 } else if (SUHOSIN7_G(eval_blacklist) != NULL) {
1272 if (zend_hash_exists(SUHOSIN7_G(eval_blacklist), function_name)) { 816 if (zend_hash_exists(SUHOSIN7_G(eval_blacklist), function_name)) {
1273 suhosin_log(S_EXECUTOR|S_GETCALLER, "function within eval blacklist called: %s()", ZSTR_VAL(function_name)); 817 suhosin_log(S_EXECUTOR|S_GETCALLER, "eval'd function blacklisted: %s()", ZSTR_VAL(function_name));
1274 if (!SUHOSIN7_G(simulation)) { 818 if (!SUHOSIN7_G(simulation)) {
1275 goto execute_internal_bailout; 819 goto execute_internal_bailout;
1276 } else { 820 } else {
1277 FUNCTION_SIMULATE_WARNING() 821 FUNCTION_SIMULATE_WARNING(ZSTR_VAL(function_name))
1278 } 822 }
1279 } 823 }
1280 } 824 }
@@ -1282,49 +826,51 @@ ZEND_API static void suhosin_execute_internal(zend_execute_data *execute_data, z
1282 826
1283 if (SUHOSIN7_G(func_whitelist) != NULL) { 827 if (SUHOSIN7_G(func_whitelist) != NULL) {
1284 if (!zend_hash_exists(SUHOSIN7_G(func_whitelist), function_name)) { 828 if (!zend_hash_exists(SUHOSIN7_G(func_whitelist), function_name)) {
1285 suhosin_log(S_EXECUTOR|S_GETCALLER, "function outside of whitelist called: %s()", ZSTR_VAL(function_name)); 829 suhosin_log(S_EXECUTOR|S_GETCALLER, "function not whitelisted: %s()", ZSTR_VAL(function_name));
1286 if (!SUHOSIN7_G(simulation)) { 830 if (!SUHOSIN7_G(simulation)) {
1287 goto execute_internal_bailout; 831 goto execute_internal_bailout;
1288 } else { 832 } else {
1289 FUNCTION_SIMULATE_WARNING() 833 FUNCTION_SIMULATE_WARNING(ZSTR_VAL(function_name))
1290 } 834 }
1291 } 835 }
1292 } else if (SUHOSIN7_G(func_blacklist) != NULL) { 836 } else if (SUHOSIN7_G(func_blacklist) != NULL) {
1293 if (zend_hash_exists(SUHOSIN7_G(func_blacklist), function_name)) { 837 if (zend_hash_exists(SUHOSIN7_G(func_blacklist), function_name)) {
1294 suhosin_log(S_EXECUTOR|S_GETCALLER, "function within blacklist called: %s()", ZSTR_VAL(function_name)); 838 suhosin_log(S_EXECUTOR|S_GETCALLER, "function blacklisted: %s()", ZSTR_VAL(function_name));
1295 if (!SUHOSIN7_G(simulation)) { 839 if (!SUHOSIN7_G(simulation)) {
1296 goto execute_internal_bailout; 840 goto execute_internal_bailout;
1297 } else { 841 } else {
1298 FUNCTION_SIMULATE_WARNING() 842 FUNCTION_SIMULATE_WARNING(ZSTR_VAL(function_name))
1299 } 843 }
1300 } 844 }
1301 } 845 }
1302 846
1303 internal_function_handler *ih; 847 suhosin_internal_function_handler *ih;
1304 int retval = 0; 848 // SDEBUG("before %d", zend_hash_exists(&ihandler_table, function_name));
1305 if ((ih = zend_hash_find_ptr(&ihandler_table, function_name))) { 849 if ((ih = zend_hash_find_ptr(&ihandler_table, function_name))) {
1306 850 // SDEBUG("AFTER");
1307 void *handler = execute_data->func->internal_function.handler; 851 void *handler = execute_data->func->internal_function.handler;
1308 852
1309 if (handler != ZEND_FN(display_disabled_function)) { 853 if (handler != ZEND_FN(display_disabled_function)) {
1310 retval = ih->handler(IH_HANDLER_PARAM_PASSTHRU); 854 retval = ih->handler(S7_IH_HANDLER_PARAM_PASSTHRU);
1311 } 855 }
1312 856
1313 } 857 }
858
859execute_internal_continue:
1314 860
1315 if (retval == 0) { 861 if (retval == SUCCESS) {
1316 old_execute_internal(execute_data, return_value); 862 old_execute_internal(execute_data, return_value);
1317 } 863 }
1318 864
1319 // if (free_lcname == 1) {
1320 // efree(lcname);
1321 // }
1322 return; 865 return;
866
1323execute_internal_bailout: 867execute_internal_bailout:
1324 // if (free_lcname == 1) { 868
1325 // efree(lcname); 869 if (function_name != NULL) {
1326 // } 870 FUNCTION_WARNING(ZSTR_VAL(function_name))
1327 FUNCTION_WARNING() 871 } else {
872 FUNCTION_WARNING("<unknown>");
873 }
1328 suhosin_bailout(); 874 suhosin_bailout();
1329} 875}
1330/* }}} */ 876/* }}} */
@@ -1332,20 +878,20 @@ execute_internal_bailout:
1332 878
1333/* {{{ int function_lookup(zend_extension *extension) 879/* {{{ int function_lookup(zend_extension *extension)
1334 */ 880 */
1335static int function_lookup(zend_extension *extension) 881// static int function_lookup(zend_extension *extension)
1336{ 882// {
1337 // if (zo_set_oe_ex != NULL) { 883// if (zo_set_oe_ex != NULL) {
1338 // return ZEND_HASH_APPLY_STOP; 884// return ZEND_HASH_APPLY_STOP;
1339 // } 885// }
1340 886//
1341 // if (extension->handle != NULL) { 887// if (extension->handle != NULL) {
1342 // 888//
1343 // zo_set_oe_ex = (void *)DL_FETCH_SYMBOL(extension->handle, "zend_optimizer_set_oe_ex"); 889// zo_set_oe_ex = (void *)DL_FETCH_SYMBOL(extension->handle, "zend_optimizer_set_oe_ex");
1344 // 890//
1345 // } 891// }
1346 892//
1347 return 0; 893// return 0;
1348} 894// }
1349/* }}} */ 895/* }}} */
1350 896
1351 897
@@ -1353,26 +899,24 @@ static int function_lookup(zend_extension *extension)
1353 */ 899 */
1354void suhosin_hook_execute() 900void suhosin_hook_execute()
1355{ 901{
1356 internal_function_handler *ih;
1357
1358 old_execute_ex = zend_execute_ex; 902 old_execute_ex = zend_execute_ex;
1359 zend_execute_ex = suhosin_execute_ex; 903 zend_execute_ex = suhosin_execute_ex;
1360 904
1361/* old_compile_file = zend_compile_file; 905/* old_compile_file = zend_compile_file;
1362 zend_compile_file = suhosin_compile_file; */ 906 zend_compile_file = suhosin_compile_file; */
1363 907
1364#if ZO_COMPATIBILITY_HACK_TEMPORARY_DISABLED 908// #if ZO_COMPATIBILITY_HACK_TEMPORARY_DISABLED
1365 if (zo_set_oe_ex == NULL) { 909// if (zo_set_oe_ex == NULL) {
1366 zo_set_oe_ex = (void *)DL_FETCH_SYMBOL(NULL, "zend_optimizer_set_oe_ex"); 910// zo_set_oe_ex = (void *)DL_FETCH_SYMBOL(NULL, "zend_optimizer_set_oe_ex");
1367 } 911// }
1368 if (zo_set_oe_ex == NULL) { 912// if (zo_set_oe_ex == NULL) {
1369 zend_llist_apply(&zend_extensions, (llist_apply_func_t)function_lookup); 913// zend_llist_apply(&zend_extensions, (llist_apply_func_t)function_lookup);
1370 } 914// }
1371 915//
1372 if (zo_set_oe_ex != NULL) { 916// if (zo_set_oe_ex != NULL) {
1373 old_execute_ZO = zo_set_oe_ex(suhosin_execute_ZO); 917// old_execute_ZO = zo_set_oe_ex(suhosin_execute_ZO);
1374 } 918// }
1375#endif 919// #endif
1376 920
1377 old_execute_internal = zend_execute_internal; 921 old_execute_internal = zend_execute_internal;
1378 if (old_execute_internal == NULL) { 922 if (old_execute_internal == NULL) {
@@ -1382,9 +926,11 @@ void suhosin_hook_execute()
1382 926
1383 /* register internal function handlers */ 927 /* register internal function handlers */
1384 zend_hash_init(&ihandler_table, 16, NULL, NULL, 1); 928 zend_hash_init(&ihandler_table, 16, NULL, NULL, 1);
1385 ih = &ihandlers[0]; 929 suhosin_internal_function_handler *ih = &ihandlers[0];
1386 while (ih->name) { 930 while (ih->name) {
1387 zend_hash_str_add_ptr(&ihandler_table, ih->name, sizeof(ih->name)-1, ih); 931 // SDEBUG("adding [%s]/%zu", ih->name, strlen(ih->name));
932 // zend_hash_str_add_ptr(&ihandler_table, ZEND_STRL(ih->name), ih);
933 zend_hash_str_add_ptr(&ihandler_table, ih->name, strlen(ih->name), ih);
1388 ih++; 934 ih++;
1389 } 935 }
1390 936
@@ -1403,11 +949,11 @@ void suhosin_hook_execute()
1403 */ 949 */
1404void suhosin_unhook_execute() 950void suhosin_unhook_execute()
1405{ 951{
1406#if ZO_COMPATIBILITY_HACK_TEMPORARY_DISABLED 952// #if ZO_COMPATIBILITY_HACK_TEMPORARY_DISABLED
1407 if (zo_set_oe_ex) { 953// if (zo_set_oe_ex) {
1408 zo_set_oe_ex(old_execute_ZO); 954// zo_set_oe_ex(old_execute_ZO);
1409 } 955// }
1410#endif 956// #endif
1411 957
1412 zend_execute_ex = old_execute_ex; 958 zend_execute_ex = old_execute_ex;
1413 959