php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #3753 is_readable() broken
Submitted: 2000-03-07 03:28 UTC Modified: 2000-03-16 13:47 UTC
From: ajung at suxers dot de Assigned:
Status: Closed Package: Misbehaving function
PHP Version: 4.0 Beta 4 Patch Level 1 OS: Solaris 2.7
Private report: No CVE-ID: None
 [2000-03-07 03:28 UTC] ajung at suxers dot de
The is_readable() function returns true for a filename that can not be accessed from the account
where the web server and my Apache runs. The file is only readable for another unprivileged user
but not the user under which Apache runs.

Andreas Jung

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2000-03-07 19:44 UTC] hholzgra at cvs dot php dot net
this one applies to is_writable() and is_executable() 
as well

they only check the owner bits and so return if the
_owner_ of the file is allowed to read, write or
execute it, not the user the current process is running as

i'll give it a short round tonight, making it compare
file owner and group to process owner and group
and use the right bits accordingly,
but that won't be perfect because a user may be in more
than one group

have to check how kernel and the groups command
figure this out ... 
 [2000-03-07 20:25 UTC] hholzgra at cvs dot php dot net
the following patch to ext/standard/filestat.c
should do most of the job

it checks for all groups a user belongs to
and it knows that root can do anything

it does not yet check for effective id's
( geteuid(), getegid() ) and i am quite
shure that the getgroups() funktion is
not available on all systems

can especially someone check this on a win32
system please ?

(won't do a cvs commit until i know better)




--- filestat.c  2000/03/06 20:37:11     1.26
+++ filestat.c  2000/03/08 01:19:47
@@ -402,6 +402,7 @@
 static void php_stat(const char *filename, int type, pval *return_value)
 {
        struct stat *stat_sb;
+       int rmask=S_IROTH,wmask=S_IWOTH,xmask=S_IXOTH; /* access rights defaults to other */
        BLS_FETCH();
 
        stat_sb = &BG(sb);
@@ -444,6 +445,35 @@
        }
 #endif
 
+
+       if(BG(sb).st_uid==getuid()) {
+               rmask=S_IRUSR;
+               wmask=S_IWUSR;
+               xmask=S_IXUSR;
+       } else if(BG(sb).st_gid==getgid()) {
+               rmask=S_IRGRP;
+               wmask=S_IWGRP;
+               xmask=S_IXGRP;
+       } else {
+               int   groups,n,i;
+               gid_t *gids;
+
+               groups = getgroups(0,NULL);
+               if(groups) {
+                       gids=(gid_t *)emalloc(groups*sizeof(gid_t));
+                       n=getgroups(groups,gids);
+                       for(i=0;i<n;i++){
+                               if(BG(sb).st_gid==gids[i]) {
+                                       rmask=S_IRGRP;
+                                       wmask=S_IWGRP;
+                                       xmask=S_IXGRP;
+                                       break;
+                               }
+                       }
+                       efree(gids);
+               }
+       }
+
        switch(type) {
        case 0: /* fileperms */
                RETURN_LONG((long)BG(sb).st_mode);
@@ -477,11 +507,14 @@
                php_error(E_WARNING,"Unknown file type (%d)",BG(sb).st_mode&S_IFMT);
                RETURN_STRING("unknown",1);
        case 9: /*is writable*/
-               RETURN_LONG((BG(sb).st_mode&S_IWRITE)!=0);
+               if(getuid()==0) RETURN_LONG(1); /* root */
+               RETURN_LONG((BG(sb).st_mode&wmask)!=0);
        case 10: /*is readable*/
-               RETURN_LONG((BG(sb).st_mode&S_IREAD)!=0);
+               if(getuid()==0) RETURN_LONG(1); /* root */
+               RETURN_LONG((BG(sb).st_mode&rmask)!=0);
        case 11: /*is executable*/
-               RETURN_LONG((BG(sb).st_mode&S_IEXEC)!=0 && !S_ISDIR(BG(sb).st_mode));
+               if(getuid()==0) RETURN_LONG(1); /* root */
+               RETURN_LONG((BG(sb).st_mode&xmask)!=0 && !S_ISDIR(BG(sb).st_mode));
        case 12: /*is file*/
                RETURN_LONG(S_ISREG(BG(sb).st_mode));
        case 13: /*is dir*/                                                                                                                  
 [2000-03-16 13:47 UTC] hholzgra at cvs dot php dot net
the patch is in
 
PHP Copyright © 2001-2026 The PHP Group
All rights reserved.
Last updated: Sat Oct 10 11:00:01 2026 UTC