I posted this to the php general list and one of the other subscribers
suggested that I post this here. It was also suggested that this might
be a bug in apache2 but before I post this every where I thought I would
try here.
I have found a funky situation that I am trying to figure out if it is
bug or not:
I see this behavior on both redhat 9 and fedora running
php 4.3.4
httpd(apache) 2.0.48
calling umask(0002) in a script leaves the httpd process with a umask of
2 after exit so that the next process to hit that process gets the new
umask. in other words the environment does not revert to default as the
umask()
docs say it should. This does not happen on my 7.3 box running
apache-1.3.27-2
php-4.1.2-7.3.6
I found this chasing a rabbit trail of a bug. This is kind of sneaky
since it only changes the umask for the single httpd process it hits.
multiple calls to umask(0002) will change every process it hits.
I distilled this down to this test:
BTW this is also file at buzilla.redhat.com as bug number 121454:
http://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=121454
1.install umask.php in a directory accessible by the web server
####### umask.php
<?php
if ( isset( $_GET['newmask']) ) {
print "newmask is set to $_GET[newmask] calling umask()
<br>\n";
print umask($_GET['newmask']) ."<br>\n";
}
else {
print "umask is ". umask()
. "<br>\n";
}
?>
################# end of umask.php
- copy chkmask.sh somwhere on the server
########## chkumask.sh
#!/bin/sh
if [ -n "$1" ] ; then
echo "setting hostname to input host $1"
myhost=$1
else
myhost=$HOSTNAME
fi
echo "using $myhost as wget host"
while [ 1 ]; do
echo -n `date +'%D'` " host: $myhost "
wget -q -O - "http://$myhost/umask.php"
sleep 1
done
############ end of of chkumask.sh
-
run chkumask.sh [hostnameofserver]
this will start looping and making calls to the umask.php script on
the server defaults to value of $HOSTNAME -
with a broser or whatever go to
http://servername/locationofumask.php?newmask=0002
5 observe output of chkumask.sh depending on the number of threads
started by httpd the umask changes from 18(octal 22, the default) to 2
for that thread.
refresh the browser several times to have more threads get changed.
Actual Results: output of chkumask.sh:
using 10.23.0.137 as wget host
04/21/04 host: 10.23.0.137 umask is 2<br>
04/21/04 host: 10.23.0.137 umask is 18<br>
04/21/04 host: 10.23.0.137 umask is 2<br>
04/21/04 host: 10.23.0.137 umask is 2<br>
04/21/04 host: 10.23.0.137 umask is 18<br>
04/21/04 host: 10.23.0.137 umask is 18<br>
04/21/04 host: 10.23.0.137 umask is 18<br>
04/21/04 host: 10.23.0.137 umask is 2<br>
04/21/04 host: 10.23.0.137 umask is 2<br>
04/21/04 host: 10.23.0.137 umask is 18<br>
04/21/04 host: 10.23.0.137 umask is 2<br>
any tips appreciated as well as report wither the behavior is seen or
not on various versions. I am trying to isolate when this behavior
started or what I have done wrong.
Bret
Patch is below; the apache2filter SAPI needs the same fix. This
"feature" of resetting the umask across requests is pretty dubious if
used with a threaded MPM, however, since the umask is a process
attribute not a thread attribute.
--- php-4.3.6/sapi/apache2handler/sapi_apache2.c.umask
+++ php-4.3.6/sapi/apache2handler/sapi_apache2.c
@@ -420,6 +420,19 @@
return APR_SUCCESS;
}
+static int saved_umask;
+static void php_save_umask(void)
+{
- saved_umask = umask(0777);
- umask(saved_umask);
+}
+static void php_restore_umask(void)
+{
- umask(saved_umask);
+}
static void php_apache_request_ctor(request_rec *r, php_struct *ctx TSRMLS_DC)
{
char *content_type;
@@ -552,6 +565,8 @@
} else {
zend_file_handle zfd = {0};
-
php_save_umask();
-
zfd.type = ZEND_HANDLE_FILENAME; zfd.filename = (char *) r->filename; zfd.free_filename = 0;
@@ -562,6 +577,9 @@
} else {
zend_execute_scripts(ZEND_INCLUDE TSRMLS_CC, NULL, 1, &zfd);
}
-
php_restore_umask();
#if MEMORY_LIMIT
{
char *mem_usage;
If at all, I think this should be fixed in PHP so that it affects all SAPIs
(i.e. first time we set umask()
save the old one and a flag that let's
RSHUTDOWN know it should change it back).
Andi
At 10:51 AM 4/22/2004 +0100, Joe Orton wrote:
Patch is below; the apache2filter SAPI needs the same fix. This
"feature" of resetting the umask across requests is pretty dubious if
used with a threaded MPM, however, since the umask is a process
attribute not a thread attribute.--- php-4.3.6/sapi/apache2handler/sapi_apache2.c.umask
+++ php-4.3.6/sapi/apache2handler/sapi_apache2.c
@@ -420,6 +420,19 @@
return APR_SUCCESS;
}+static int saved_umask;
+static void php_save_umask(void)
+{
saved_umask = umask(0777);
umask(saved_umask);
+}
+static void php_restore_umask(void)
+{
umask(saved_umask);
+}
static void php_apache_request_ctor(request_rec *r, php_struct *ctx
TSRMLS_DC)
{
char *content_type;
@@ -552,6 +565,8 @@
} else {
zend_file_handle zfd = {0};
php_save_umask();
zfd.type = ZEND_HANDLE_FILENAME; zfd.filename = (char *) r->filename; zfd.free_filename = 0;
@@ -562,6 +577,9 @@
} else {
zend_execute_scripts(ZEND_INCLUDE TSRMLS_CC,
NULL, 1, &zfd);
}
php_restore_umask();
#if MEMORY_LIMIT
{
char *mem_usage;
If at all, I think this should be fixed in PHP so that it affects all SAPIs
(i.e. first time we setumask()
save the old one and a flag that let's
RSHUTDOWN know it should change it back).
(In case it wasn't clear, all my patch did was copy the logic used by
sapi/apache)