On Thu, 20 Jun 2002, C. McCohy wrote:
> it's going about the safe_mode_exec_dir configuration directive, which
> allows php script to execute an external command, which is located in
> specified directory only. This is able only in safe mode, not in "normal
> mode" ..
>
> What do you think, would it be nice to have this feature outside the
> safe mode? I think it would be _very_ nice for some security reasons ...
OK, no answer is better than the negative one ;-)))
The patch follows ... I've tested it many times, should work fine ...
It provides the "exec_dir" configuration directive which allows user to
execute external commands located only in specified directory, if safe
mode is disabled. If safe mode is enabled, this directive is forgotten and
safe_mode_exec_dir will be used instead.
So if you think it is a good idea, add it ...
--
Bye .. C. McCohy
The killings will not stop until you Karel Roden
-----------------------------------------------------------------------
diff -uar php-4.2.1.orig/ext/standard/exec.c php-4.2.1/ext/standard/exec.c
--- php-4.2.1.orig/ext/standard/exec.c Thu Apr 25 16:02:51 2002
+++ php-4.2.1/ext/standard/exec.c Fri Jun 21 08:48:51 2002
@@ -111,6 +111,50 @@
return -1;
}
+ } else if (PG(exec_dir)) {
+ /* _NO_ safe mode with exec_dir enabled */
+
+ d = emalloc(strlen(PG(exec_dir)) + strlen(cmd) + 2);
+ c = strchr(cmd, ' ');
+ if (c) *c = '\0';
+ if (strstr(cmd, "..")) {
+ php_error(E_WARNING, "No '..' components allowed in path");
+ efree(d);
+ efree(buf);
+ return -1;
+ }
+ b = strrchr(cmd, PHP_DIR_SEPARATOR);
+ strcpy(d, PG(exec_dir));
+ if (b) {
+ strcat(d, b);
+ } else {
+ sprintf(d, "%s%c%s", d, PHP_DIR_SEPARATOR, cmd);
+ }
+ if (c) {
+ *c = ' ';
+ strcat(d, c);
+ }
+ tmp = php_escape_shell_cmd(d);
+ efree(d);
+ d = tmp;
+
+#if PHP_SIGCHILD
+ sig_handler = signal (SIGCHLD, SIG_DFL);
+#endif
+#ifdef PHP_WIN32
+ fp = VCWD_POPEN(d, "rb");
+#else
+ fp = VCWD_POPEN(d, "r");
+#endif
+ if (!fp) {
+ php_error(E_WARNING, "Unable to fork [%s]", d);
+ efree(d);
+ efree(buf);
+#if PHP_SIGCHILD
+ signal (SIGCHLD, sig_handler);
+#endif
+ return -1;
+ }
} else { /* not safe_mode */
#if PHP_SIGCHILD
sig_handler = signal (SIGCHLD, SIG_DFL);
@@ -122,6 +166,7 @@
#endif
if (!fp) {
php_error(E_WARNING, "Unable to fork [%s]", cmd);
+ efree(d);
efree(buf);
#if PHP_SIGCHILD
signal (SIGCHLD, sig_handler);
@@ -129,6 +174,7 @@
return -1;
}
}
+
buf[0] = '\0';
if (type==2) {
if (Z_TYPE_P(array) != IS_ARRAY) {
@@ -453,13 +499,48 @@
}
convert_to_string_ex(cmd);
+
+ if(PG(exec_dir)) {
+ char *d, *b;
+ b = strchr(Z_STRVAL_PP(cmd), ' ');
+ if (!b) {
+ b = strrchr(Z_STRVAL_PP(cmd), PHP_DIR_SEPARATOR);
+ } else {
+ char *c;
+ c = Z_STRVAL_PP(cmd);
+ while ((*b != PHP_DIR_SEPARATOR) && (b != c)) {
+ b--;
+ }
+ if (b == c) {
+ b = NULL;
+ }
+ }
+
+ d = emalloc(Z_STRLEN_PP(cmd) + strlen(PG(exec_dir)) + 2);
+ if (b) {
+ strcpy(d, PG(exec_dir));
+ strcat(d, b);
+ } else {
+ sprintf(d, "%s%c%s", PG(exec_dir), PHP_DIR_SEPARATOR,
+Z_STRVAL_PP(cmd));
+ }
+
#ifdef PHP_WIN32
- if ((in=VCWD_POPEN(Z_STRVAL_PP(cmd), "rt"))==NULL) {
+ if ((in=VCWD_POPEN(d, "rt"))==NULL) {
#else
- if ((in=VCWD_POPEN(Z_STRVAL_PP(cmd), "r"))==NULL) {
+ if ((in=VCWD_POPEN(d, "r"))==NULL) {
#endif
- php_error(E_WARNING, "Unable to execute '%s'", Z_STRVAL_PP(cmd));
- RETURN_FALSE;
+ php_error(E_WARNING, "Unable to execute '%s'", d);
+ RETURN_FALSE;
+ }
+ } else {
+#ifdef PHP_WIN32
+ if ((in=VCWD_POPEN(Z_STRVAL_PP(cmd), "rt"))==NULL) {
+#else
+ if ((in=VCWD_POPEN(Z_STRVAL_PP(cmd), "r"))==NULL) {
+#endif
+ php_error(E_WARNING, "Unable to execute '%s'",
+Z_STRVAL_PP(cmd));
+ RETURN_FALSE;
+ }
}
allocated_space = EXEC_INPUT_BUF;
ret = (char *) emalloc(allocated_space);
diff -uar php-4.2.1.orig/ext/standard/file.c php-4.2.1/ext/standard/file.c
--- php-4.2.1.orig/ext/standard/file.c Sun May 12 18:08:31 2002
+++ php-4.2.1/ext/standard/file.c Fri Jun 21 08:25:52 2002
@@ -722,6 +722,34 @@
php_error(E_WARNING, "popen(\"%s\", \"%s\") - %s", buf, p,
strerror(errno));
RETURN_FALSE;
}
+ } else if (PG(exec_dir)) {
+ b = strchr(Z_STRVAL_PP(arg1), ' ');
+ if (!b) {
+ b = strrchr(Z_STRVAL_PP(arg1), PHP_DIR_SEPARATOR);
+ } else {
+ char *c;
+ c = Z_STRVAL_PP(arg1);
+ while ((*b != PHP_DIR_SEPARATOR) && (b != c)) {
+ b--;
+ }
+ if (b == c) {
+ b = NULL;
+ }
+ }
+ if (b) {
+ snprintf(buf, sizeof(buf), "%s%s", PG(exec_dir), b);
+ } else {
+ snprintf(buf, sizeof(buf), "%s%c%s", PG(exec_dir),
+PHP_DIR_SEPARATOR, Z_STRVAL_PP(arg1));
+ }
+
+ tmp = php_escape_shell_cmd(buf);
+ fp = VCWD_POPEN(tmp, p);
+ efree(tmp);
+
+ if (!fp) {
+ php_error(E_WARNING, "popen(\"%s\", \"%s\") - %s", buf, p,
+strerror(errno));
+ RETURN_FALSE;
+ }
} else {
fp = VCWD_POPEN(Z_STRVAL_PP(arg1), p);
if (!fp) {
diff -uar php-4.2.1.orig/main/main.c php-4.2.1/main/main.c
--- php-4.2.1.orig/main/main.c Sat Mar 9 01:26:40 2002
+++ php-4.2.1/main/main.c Thu Jun 20 12:06:26 2002
@@ -259,6 +259,7 @@
PHP_INI_ENTRY("max_execution_time", "30",
PHP_INI_ALL, OnUpdateTimeout)
STD_PHP_INI_ENTRY("open_basedir", NULL,
PHP_INI_SYSTEM, OnUpdateStringUnempty, open_basedir,
php_core_globals, core_globals)
STD_PHP_INI_ENTRY("safe_mode_exec_dir", "1",
PHP_INI_SYSTEM, OnUpdateString, safe_mode_exec_dir,
php_core_globals, core_globals)
+ STD_PHP_INI_ENTRY("exec_dir", NULL,
+PHP_INI_SYSTEM, OnUpdateString, exec_dir,
+ php_core_globals, core_globals)
STD_PHP_INI_ENTRY("upload_max_filesize", "2M", PHP_INI_ALL,
OnUpdateInt, upload_max_filesize, php_core_globals,
core_globals)
STD_PHP_INI_ENTRY("file_uploads", "1",
PHP_INI_ALL, OnUpdateBool, file_uploads,
php_core_globals, core_globals)
STD_PHP_INI_ENTRY("post_max_size", "8M",
PHP_INI_SYSTEM, OnUpdateInt, post_max_size,
sapi_globals_struct,sapi_globals)
diff -uar php-4.2.1.orig/main/php_globals.h php-4.2.1/main/php_globals.h
--- php-4.2.1.orig/main/php_globals.h Thu Feb 28 09:27:03 2002
+++ php-4.2.1/main/php_globals.h Thu Jun 20 09:49:14 2002
@@ -69,6 +69,7 @@
char *unserialize_callback_func;
char *safe_mode_exec_dir;
+ char *exec_dir;
long memory_limit;
diff -uar php-4.2.1.orig/php.ini-dist php-4.2.1/php.ini-dist
--- php-4.2.1.orig/php.ini-dist Mon Apr 8 03:15:16 2002
+++ php-4.2.1/php.ini-dist Thu Jun 20 17:25:53 2002
@@ -390,6 +390,11 @@
; cause security issues, KNOW WHAT YOU ARE DOING FIRST.
; cgi.redirect_status_env = ;
+; Only executables located in the exec_dir will be allowed to be executed
+; via the exec family of functions. If safe_mode is enabled, this directive
+; is forgotten and safe_mode_exec_dir takes the ride
+exec_dir =
+
;;;;;;;;;;;;;;;;
; File Uploads ;
;;;;;;;;;;;;;;;;
diff -uar php-4.2.1.orig/php.ini-recommended php-4.2.1/php.ini-recommended
--- php-4.2.1.orig/php.ini-recommended Wed Apr 24 03:51:50 2002
+++ php-4.2.1/php.ini-recommended Thu Jun 20 17:26:24 2002
@@ -395,7 +395,10 @@
; cause security issues, KNOW WHAT YOU ARE DOING FIRST.
; cgi.redirect_status_env = ;
-
+; Only executables located in the exec_dir will be allowed to be executed
+; via the exec family of functions. If safe_mode is enabled, this directive
+; is forgotten and safe_mode_exec_dir takes the ride
+exec_dir =
;;;;;;;;;;;;;;;;
; File Uploads ;
--
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php