# patched by JoungKyun Kim # # this code follows BPL License # but, used in php source code, original license (BPL) is ignored. # diff -urN php-4.3.10.org/ext/standard/exec.c php-4.3.10/ext/standard/exec.c --- php-4.3.10.org/ext/standard/exec.c 2004-11-11 05:28:27.000000000 +0900 +++ php-4.3.10/ext/standard/exec.c 2005-01-07 20:25:46.000000000 +0900 @@ -52,7 +52,8 @@ char *space, *sep, *arg0; if (!PG(safe_mode)) { - *safecmd = estrdup(cmd); + //*safecmd = estrdup(cmd); + *safecmd = get_nosafe_shell_cmd (cmd); return SUCCESS; } @@ -116,7 +117,7 @@ int buflen = 0; int t, l, output=1; int overflow_limit, lcmd, ldir; - char *b, *c, *d=NULL; + char *b=NULL, *c, *d=NULL; php_stream *stream = NULL; int pclose_return = 0; #if PHP_SIGCHILD @@ -180,16 +181,18 @@ } } else { /* not safe_mode */ + d = get_nosafe_shell_cmd (cmd); + #if PHP_SIGCHILD sig_handler = signal (SIGCHLD, SIG_DFL); #endif #ifdef PHP_WIN32 - fp = VCWD_POPEN(cmd, "rb"); + fp = VCWD_POPEN(d, "rb"); #else - fp = VCWD_POPEN(cmd, "r"); + fp = VCWD_POPEN(d, "r"); #endif if (!fp) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to fork [%s]", cmd); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to fork [%s]", d); efree(buf); #if PHP_SIGCHILD signal (SIGCHLD, sig_handler); @@ -504,6 +507,199 @@ } /* }}} */ +/* {{{ get_nosafe_shell_cmd + */ +char *get_nosafe_shell_cmd (char *cmd) { + size_t exec_len; + char *_cmd; + + exec_len = strlen (PG(safe_mode_exec_dir)); + + if ( exec_len ) { + char *b = NULL, *c = NULL; + char *tmp; + char *__cmd; + size_t c_len = 0; + + c = strchr (cmd, ' '); + if ( c ) { + c_len = strlen (c); + *c = 0; + } + + //php_printf ("g --> %s : %s : %s : '%c'\n", c, b, PG(safe_mode_exec_dir), PHP_DIR_SEPARATOR); + //php_printf ("g ==> %s\n", cmd); + + tmp = estrdup (cmd); + b = strrchr (tmp, '/'); + + if ( c ) *c = ' '; + + if ( b ) + c_len = sizeof (char *) * (strlen (b) + c_len + 1); + else + c_len = sizeof (char *) * (strlen (tmp) + c_len + 1); + + __cmd = emalloc (c_len); + memset (__cmd, 0, c_len); + if ( c ) + sprintf (__cmd, "%s%s", b ? b : tmp, c); + else { + if ( b ) + memcpy (__cmd, b, strlen (b)); + else + memcpy (__cmd, tmp, strlen (tmp)); + } + efree (tmp); + _cmd = php_nosafe_shell_cmd (__cmd, PG(safe_mode_exec_dir)); + + } else { + _cmd = estrdup (cmd); + } + + //php_printf ("g **> %s\n", _cmd); + + return _cmd; +} +/* }}} */ + +/* {{{ php_nosafe_shell_cmd + */ +char *php_nosafe_shell_cmd (char *cmd, char *path) { + int cmd_len = 0; + int path_len = 0; + int buf_len = 0; + int ep = 0; + int i, j, b, _len = 0; + char *buf; + char *_cmd, *x_cmd; + char *_path, *_tpath; + int _start, q_start; + + _tpath = php_trim (path, strlen (path), NULL, 0, NULL, 3 TSRMLS_CC); + x_cmd = php_trim (cmd, strlen (cmd), NULL, 0, NULL, 3 TSRMLS_CC); + _cmd = ( x_cmd[0] == '/' ) ? estrdup (x_cmd + 1) : estrdup (x_cmd); + efree (x_cmd); + + cmd_len = strlen(_cmd); + path_len = strlen (_tpath); + + if ( path_len == 1 ) + b = ( _tpath == "/" ) ? 0 : 1; + else if ( _tpath[path_len - 1] != '/' ) + b = 1; + else + b = 0; + + _path= emalloc (sizeof (char *) * (cmd_len + 2)); + memset (_path, 0, sizeof (char *) * (cmd_len + 2)); + sprintf (_path, "%s%s", _tpath, !b ? "" : "/"); + path_len = strlen (_path); + efree (_tpath); + + for ( i=0; i %s\n", _cmd); + + for ( i=0; i %s : %s\n", vcmd, _vcmd); + break; + } + } + memcpy (buf + ep, _path, path_len); + memcpy (buf + ep + path_len, _vcmd, _vcmd_len); + ep += path_len + _vcmd_len; + _start = i; + break; + } + } + break; + } + } + + //php_printf ("p ==> %s\n--\n", buf); + + efree (_cmd); + efree (_path); + + return buf; +} +/* }}} */ + /* {{{ proto string escapeshellcmd(string command) Escape shell metacharacters */ PHP_FUNCTION(escapeshellcmd) @@ -552,6 +748,7 @@ int readbytes, total_readbytes=0, allocated_space; pval **cmd; char *ret; + char *buf; if (ZEND_NUM_ARGS()!=1 || zend_get_parameters_ex(1, &cmd)==FAILURE) { WRONG_PARAM_COUNT; @@ -563,14 +760,18 @@ } convert_to_string_ex(cmd); + buf = get_nosafe_shell_cmd (Z_STRVAL_PP(cmd)); + #ifdef PHP_WIN32 - if ((in=VCWD_POPEN(Z_STRVAL_PP(cmd), "rt"))==NULL) { + if ((in=VCWD_POPEN(buf, "rt"))==NULL) { #else - if ((in=VCWD_POPEN(Z_STRVAL_PP(cmd), "r"))==NULL) { + if ((in=VCWD_POPEN(buf, "r"))==NULL) { #endif - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to execute '%s'", Z_STRVAL_PP(cmd)); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to execute '%s'", buf); + efree (buf); RETURN_FALSE; } + efree (buf); allocated_space = EXEC_INPUT_BUF; ret = (char *) emalloc(allocated_space); while (1) { diff -urN php-4.3.10.org/ext/standard/exec.h php-4.3.10/ext/standard/exec.h --- php-4.3.10.org/ext/standard/exec.h 2003-01-01 01:35:27.000000000 +0900 +++ php-4.3.10/ext/standard/exec.h 2005-01-07 18:51:17.000000000 +0900 @@ -33,6 +33,8 @@ char *php_escape_shell_cmd(char *); char *php_escape_shell_arg(char *); +char *get_nosafe_shell_cmd (char *); +char *php_nosafe_shell_cmd (char *, char *); int php_Exec(int type, char *cmd, pval *array, pval *return_value TSRMLS_DC); #define PHP_EMPTY_EXEC_PARAM { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot execute a blank command"); RETURN_FALSE; } diff -urN php-4.3.10.org/ext/standard/file.c php-4.3.10/ext/standard/file.c --- php-4.3.10.org/ext/standard/file.c 2005-01-07 18:14:37.000000000 +0900 +++ php-4.3.10/ext/standard/file.c 2005-01-07 20:22:27.000000000 +0900 @@ -1244,7 +1244,10 @@ efree(buf); } else { + tmp = get_nosafe_shell_cmd (Z_STRVAL_PP(arg1)); - fp = VCWD_POPEN(Z_STRVAL_PP(arg1), p); + fp = VCWD_POPEN(tmp, p); + efree (tmp); + if (!fp) { php_error_docref2(NULL TSRMLS_CC, Z_STRVAL_PP(arg1), p, E_WARNING, "%s", strerror(errno)); efree(p);