diff options
| author | James E. Flemer <jflemer@php.net> | 2001-07-13 18:21:21 +0000 |
|---|---|---|
| committer | James E. Flemer <jflemer@php.net> | 2001-07-13 18:21:21 +0000 |
| commit | 771e3e498fad6adcdc63d03ab97d4ff1f93a3987 (patch) | |
| tree | 7cc1ecaa721adb2f927d947d5b61dae10760a42d /main/safe_mode.c | |
| parent | b9325a36a8df9619e4485b166516cff1e9193406 (diff) | |
| download | php-git-771e3e498fad6adcdc63d03ab97d4ff1f93a3987.tar.gz | |
o Fixed Bug #12121: chdir and safe_mode
- [ main/safe_mode.h ] added new checkuid mode:
CHECKUID_ALLOW_ONLY_FILE: skips directory check if file check
fails
- [ ext/standard/dir.c ] changed php_checkuid() to use
CHECKUID_ALLOW_ONLY_FILE instead of CHECKUID_ALLOW_ONLY_DIR
- [ main/safe_mode.c ] added code for new checkuid mode
o Fixed Bug #12119: safe mode owner check can be bypassed with symlink
- [ main/safe_mode.c ] use VCWD_REALPATH to resolve destination
of symlink before trimming filename
o New Feature: safe_mode_include_dir (php.ini directive)
- Allows bypassing UID/GID checks when including files
from the directory in safe_mode_include_dir and its
subdirectories. (safe_mode must be on, directory must
also be in include_path or full path must be used when
including)
o Fixed Feature: safe_mode_gid (php.ini directive)
- Correctly check (and report) UID/GID bits on directories
o Changed include() fall back to scripts cwd implementation
- CWD added to the (local) search path in php_fopen_with_path()
instead of seperate case. [ main/fopen_wrappers.c ]
Diffstat (limited to 'main/safe_mode.c')
| -rw-r--r-- | main/safe_mode.c | 93 |
1 files changed, 51 insertions, 42 deletions
diff --git a/main/safe_mode.c b/main/safe_mode.c index e251d37b26..f20fe516c4 100644 --- a/main/safe_mode.c +++ b/main/safe_mode.c @@ -48,6 +48,7 @@ PHPAPI int php_checkuid(const char *filename, char *fopen_mode, int mode) struct stat sb; int ret; long uid=0L, gid=0L, duid=0L, dgid=0L; + char path[MAXPATHLEN]; char *s; PLS_FETCH(); @@ -71,8 +72,12 @@ PHPAPI int php_checkuid(const char *filename, char *fopen_mode, int mode) return 1; } + /* First we see if the file is owned by the same user... + * If that fails, passthrough and check directory... + */ if (mode != CHECKUID_ALLOW_ONLY_DIR) { - ret = VCWD_STAT(filename, &sb); + VCWD_REALPATH(filename, path); + ret = VCWD_STAT(path, &sb); if (ret < 0) { if (mode == CHECKUID_DISALLOW_FILE_NOT_EXISTS) { php_error(E_WARNING, "Unable to access %s", filename); @@ -83,63 +88,67 @@ PHPAPI int php_checkuid(const char *filename, char *fopen_mode, int mode) } } else { uid = sb.st_uid; + gid = sb.st_gid; if (uid == php_getuid()) { return 1; + } else if (PG(safe_mode_gid) && gid == php_getgid()) { + return 1; } } - } - s = strrchr(filename,'/'); - /* This loop gets rid of trailing slashes which could otherwise be - * used to confuse the function. - */ - while(s && *(s+1)=='\0' && s>filename) { - *s='\0'; - s = strrchr(filename,'/'); - } + /* Trim off filename */ + if (s = strrchr(path,DEFAULT_SLASH)) { + *s = '\0'; + } + } else { /* CHECKUID_ALLOW_ONLY_DIR */ + s = strrchr(filename,DEFAULT_SLASH); - if (s) { - *s='\0'; - ret = VCWD_STAT(filename, &sb); - *s='/'; + if (s) { + *s = '\0'; + VCWD_REALPATH(filename, path); + *s = DEFAULT_SLASH; + } else { + VCWD_GETCWD(path, MAXPATHLEN); + } + } /* end CHECKUID_ALLOW_ONLY_DIR */ + + if (mode != CHECKUID_ALLOW_ONLY_FILE) { + /* check directory */ + ret = VCWD_STAT(path, &sb); if (ret < 0) { php_error(E_WARNING, "Unable to access %s", filename); return 0; } duid = sb.st_uid; - } else { - char cwd[MAXPATHLEN]; - if (!VCWD_GETCWD(cwd, MAXPATHLEN)) { - php_error(E_WARNING, "Unable to access current working directory"); - return 0; - } - ret = VCWD_STAT(cwd, &sb); - if (ret < 0) { - php_error(E_WARNING, "Unable to access %s", cwd); - return 0; - } - duid = sb.st_uid; - } - if (duid == (uid=php_getuid())) { - return 1; - } else if (PG(safe_mode_gid) && dgid == (gid=php_getgid())) { - return 1; - } else { - SLS_FETCH(); + dgid = sb.st_gid; + if (duid == php_getuid()) { + return 1; + } else if (PG(safe_mode_gid) && dgid == php_getgid()) { + return 1; + } else { + SLS_FETCH(); - if (SG(rfc1867_uploaded_files)) { - if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, strlen(filename)+1)) { - return 1; + if (SG(rfc1867_uploaded_files)) { + if (zend_hash_exists(SG(rfc1867_uploaded_files), (char *) filename, strlen(filename)+1)) { + return 1; + } } } + } - if (PG(safe_mode_gid)) { - php_error(E_WARNING, "SAFE MODE Restriction in effect. The script whose uid/gid is %ld/%ld is not allowed to access %s owned by uid/gid %ld/%ld", uid, gid, filename, duid, dgid); - } else { - php_error(E_WARNING, "SAFE MODE Restriction in effect. The script whose uid is %ld is not allowed to access %s owned by uid %ld", uid, filename, duid); - } - return 0; + if (mode == CHECKUID_ALLOW_ONLY_DIR) { + uid = duid; + gid = dgid; + if (s) { + *s = 0; + } } + if (PG(safe_mode_gid)) { + php_error(E_WARNING, "SAFE MODE Restriction in effect. The script whose uid/gid is %ld/%ld is not allowed to access %s owned by uid/gid %ld/%ld", php_getuid(), php_getgid(), filename, uid, gid); + } else { + php_error(E_WARNING, "SAFE MODE Restriction in effect. The script whose uid is %ld is not allowed to access %s owned by uid %ld", php_getuid(), filename, uid); + } + return 0; } |
