Hi php-dev,

gccs automatic warnings are nice, but unfortunately they do NOT trigger 
during shared library builds.

In our ongoing audit I have spotted several /tmp vulnerabilities in PHP 3.

./functions/file.c:void php3_tempnam(INTERNAL_FUNCTION_PARAMETERS) {
./functions/file.c:     t = tempnam(d,p);
        
        This is the implementation of the PHP function 'tempnam'.

        In PHP4 this functions uses 'mkstemp' and so changes the semantics.
        My patch below also does this, but we should warn admins that it
        does so they don't find their /tmp/ filled unexpectedly.

./functions/hg_comm.c:                                          sscanf(str, "%s\n", 
tempname);
./functions/hg_comm.c:                                          sscanf(str, "%s\n", 
tempname);
./functions/hg_comm.c:                                  sprintf(temp, "%s", tempname);
./functions/hg_comm.c:          char *temprec, *str, tempname[100];
./functions/hg_comm.c:                          sscanf(str, "%s\n", tempname);
./functions/hg_comm.c:                          sscanf(str, "%s\n", tempname);
./functions/hg_comm.c:                  sprintf(temp, "%s", tempname);
        
        hg_comm.c is compiled only in if HYPERWAVE (commercial add on?) is
        enabled. We don't have that enabled.

        Otherwise you already see several unchecked sscanf() into stack
        arrays above.
        This mail does not address these buffer overflow problems.

./functions/mime.c:                             fn = tempnam(php3_ini.upload_tmp_dir, 
"php");
                        ... followed some lines later by ...
                                fp = fopen(fn, "w");
                                                
./functions/post.c:     fn = tempnam(php3_ini.upload_tmp_dir, "php");
        fn = tempnam(php3_ini.upload_tmp_dir, "php");
        fp = fopen(fn, "w");
 
Default configurations leaves the uploaddirectory empty, so this is using
/tmp most likely.

I have attached a patch which compiles but is untested. Please review.

Ciao, Marcus

--- php-3.0.18/functions/mime.c.mkstemp Tue Oct 17 03:30:59 2000
+++ php-3.0.18/functions/mime.c Thu Jan 11 16:24:00 2001
@@ -224,7 +224,6 @@
                                        php3_error(E_WARNING, "File Upload Error - No 
Mime boundary found after start of file header");
                                        SAFE_RETURN;
                                }
-                               fn = tempnam(php3_ini.upload_tmp_dir, "php");
                                if ((loc - ptr - 4) > php3_ini.upload_max_filesize) {
                                        php3_error(E_WARNING, "Max file size of %ld 
bytes exceeded - file [%s] not saved", php3_ini.upload_max_filesize,namebuf);
                                        bytes=0;        
@@ -242,8 +241,23 @@
                                        if(memcmp(namebuf,sbuf,strlen(sbuf)))
                                                _php3_parse_gpc_data(estrdup("none"), 
namebuf, http_post_vars);
                                } else {
-                                       fp = fopen(fn, "w");
+                                       int fd;
+                                       char *fn = 
+emalloc((php3_ini.upload_tmp_dir?strlen(php3_ini.upload_tmp_dir):strlen("/tmp"))+strlen("/php.XXXXXX")+1);
+
+                                       if (php3_ini.upload_tmp_dir)
+                                               strcpy(fn,php3_ini.upload_tmp_dir);
+                                       else
+                                               strcpy(fn,"/tmp");
+                                       strcat(fn,"/php.XXXXXX");
+                                       fd = mkstemp(fn);
+                                       if (fd == -1) {
+                                               efree(fn);
+                                               return;
+                                       }
+                                       fp = fdopen(fd, "w");
                                        if (!fp) {
+                                               unlink(fn);
+                                               efree(fn);
                                                php3_error(E_WARNING, "File Upload 
Error - Unable to open temporary file [%s]", fn);
                                                SAFE_RETURN;
                                        }
--- php-3.0.18/functions/post.c.mkstemp Tue Oct  3 21:41:10 2000
+++ php-3.0.18/functions/post.c Thu Jan 11 16:29:28 2001
@@ -53,7 +53,7 @@
        size_t bytes=0;
        char *fn;
        FILE *fp;
-       int length, cnt;
+       int fd, length, cnt;
 
        length = GLOBAL(request_info).content_length;
        if (length > php3_ini.upload_max_filesize) {
@@ -61,10 +61,23 @@
                SET_VAR_STRING("PHP_PUT_FILENAME", estrdup("none"));
                return;
        }
-       fn = tempnam(php3_ini.upload_tmp_dir, "php");
-       fp = fopen(fn, "w");
+       fn = 
+(char*)emalloc((php3_ini.upload_tmp_dir?strlen(php3_ini.upload_tmp_dir):strlen("/tmp"))+strlen("php.XXXXXX")+1);
+       if (php3_ini.upload_tmp_dir)
+               strcpy(fn,php3_ini.upload_tmp_dir);
+       else
+               strcpy(fn,"/tmp");
+       strcat(fn,"/php.XXXXXX");
+       fd = mkstemp(fn);
+       if (fd == -1) {
+               php3_error(E_WARNING, "File Upload Error - Unable to open temporary 
+file [%s]", fn);
+               efree(fn);
+               return;
+       }
+       fp = fdopen(fd, "w");
        if (!fp) {
                php3_error(E_WARNING, "File Upload Error - Unable to open temporary 
file [%s]", fn);
+               unlink(fn);
+               efree(fn);
                return;
        }
        cnt = length;
--- php-3.0.18/functions/file.c.mkstemp Thu Jan 11 16:33:56 2001
+++ php-3.0.18/functions/file.c Thu Jan 11 16:36:58 2001
@@ -450,6 +450,7 @@
        char *d;
        char *t;
        char p[64];
+       int  fd;
        TLS_VARS;
        
        if (ARG_COUNT(ht) != 2 || getParameters(ht, 2, &arg1, &arg2) == FAILURE) {
@@ -460,9 +461,15 @@
        d = estrndup(arg1->value.str.val,arg1->value.str.len);
        strncpy(p,arg2->value.str.val,sizeof(p));
 
-       t = tempnam(d,p);
+       t = emalloc(strlen(d)+strlen(p)+2);
+       if (t == NULL) {
+               RETURN_FALSE;
+       }
+       strcpy(t,d);strcat(t,"/");strcat(t,p);
        efree(d);
-       if(!t) {
+       fd = mkstemp(t);
+       if (fd == -1) {
+               efree(t);
                RETURN_FALSE;
        }
        RETURN_STRING(t,1);

----- End forwarded message -----

-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to