From: roel at qsp dot nl Operating system: FreeBSD 6 PHP version: 5.1.6 PHP Bug Type: Session related Bug description: Extra options in session.save_path cause verification on update to fail
Description: ------------ Introduction ------------ The file based session handler uses the session.save_path ini variable to determine where to write it's session files. However, it also attempts to parse two other bits of information out of session.save_path, iff session.save_path contains one or two semi-colons. The format is: "[x;[y;]]pathname" Where both x and y are optional and x is a directory hashing depth for session files (defaults to 0) and y is the create mode for new session files, defaults to 0700. Whenever session.save_path is updated, a verification function is called. For this variable, this is the funtion "static PHP_INI_MH(OnUpdateSaveDir)" contained in ext/session/session.c. There is no verification in this function if PHP is running in regular mode. However, when in safe-mode, this function performs two verifications. First, it attempts to check ownership of the directory, and secondly, it does a php_check_open_basedir() on the path supplied. Problem description ------------------- In this function, OnUpdateSaveDir() in ext/session/session.c, no attempt is made to recognize and take out the optional parameters contained in the supplied new session.save_path value. So, when setting session.save_path to "0;0707;/whatever", PHP will supply php_checkuid() and php_check_open_basedir with the entire string, not just with /whatever. This causes the check to fail. Patch ------ The following patch should be applied to ext/session/session.c to fix this problem: *** ext/session/session.orig.c Fri Sep 29 11:35:05 2006 --- ext/session/session.c Fri Sep 29 12:39:26 2006 *************** *** 133,145 **** static PHP_INI_MH(OnUpdateSaveDir) { /* Only do the safemode/open_basedir check at runtime */ if (stage == PHP_INI_STAGE_RUNTIME) { ! if (PG(safe_mode) && (!php_checkuid(new_value, NULL, CHECKUID_ALLOW_ONLY_DIR))) { return FAILURE; } ! if (php_check_open_basedir(new_value TSRMLS_CC)) { return FAILURE; } } --- 133,150 ---- static PHP_INI_MH(OnUpdateSaveDir) { + char *p, *q; + int i; /* Only do the safemode/open_basedir check at runtime */ if (stage == PHP_INI_STAGE_RUNTIME) { ! /* Parse out optional hash level & file mode */ ! for (i=0, q=new_value; i<2 && (p=strchr(q, ';'))!=NULL; q=p+1, i++); ! ! if (PG(safe_mode) && (!php_checkuid(q, NULL, CHECKUID_ALLOW_ONLY_DIR))) { return FAILURE; } ! if (php_check_open_basedir(q TSRMLS_CC)) { return FAILURE; } } Remarks -------- Both parameters are, at least for the most part, undocumented. It would not be a bad idea to update the session.save_path description with information about these two variables. Submitted: 29/9/2006 Patch author: Roel Bouwman <[EMAIL PROTECTED]> Reproduce code: --------------- <?php /* Preconditions: * - server running in safe mode * - /whatever and this script owned by samed user. */ ini_set("session.save_path","0;0707;/whatever"); ?> Expected result: ---------------- 1. PHP checking wether "/whatever" is owned by script owner. 2. PHP performing basepath check for "/whatever" 3. session.save_path set to "0;0707;/whatever". Actual result: -------------- PHP will produce an error claiming that it cannot open the save_path directory as the uid check is performed not just for /whatever, but for the entire string. Result is that session.save_path will not be modified. -- Edit bug report at http://bugs.php.net/?id=38993&edit=1 -- Try a CVS snapshot (PHP 4.4): http://bugs.php.net/fix.php?id=38993&r=trysnapshot44 Try a CVS snapshot (PHP 5.2): http://bugs.php.net/fix.php?id=38993&r=trysnapshot52 Try a CVS snapshot (PHP 6.0): http://bugs.php.net/fix.php?id=38993&r=trysnapshot60 Fixed in CVS: http://bugs.php.net/fix.php?id=38993&r=fixedcvs Fixed in release: http://bugs.php.net/fix.php?id=38993&r=alreadyfixed Need backtrace: http://bugs.php.net/fix.php?id=38993&r=needtrace Need Reproduce Script: http://bugs.php.net/fix.php?id=38993&r=needscript Try newer version: http://bugs.php.net/fix.php?id=38993&r=oldversion Not developer issue: http://bugs.php.net/fix.php?id=38993&r=support Expected behavior: http://bugs.php.net/fix.php?id=38993&r=notwrong Not enough info: http://bugs.php.net/fix.php?id=38993&r=notenoughinfo Submitted twice: http://bugs.php.net/fix.php?id=38993&r=submittedtwice register_globals: http://bugs.php.net/fix.php?id=38993&r=globals PHP 3 support discontinued: http://bugs.php.net/fix.php?id=38993&r=php3 Daylight Savings: http://bugs.php.net/fix.php?id=38993&r=dst IIS Stability: http://bugs.php.net/fix.php?id=38993&r=isapi Install GNU Sed: http://bugs.php.net/fix.php?id=38993&r=gnused Floating point limitations: http://bugs.php.net/fix.php?id=38993&r=float No Zend Extensions: http://bugs.php.net/fix.php?id=38993&r=nozend MySQL Configuration Error: http://bugs.php.net/fix.php?id=38993&r=mysqlcfg