php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #38993 Extra options in session.save_path cause verification on update to fail
Submitted: 2006-09-29 14:31 UTC Modified: 2006-10-01 21:00 UTC
From: roel at qsp dot nl Assigned:
Status: Closed Package: Session related
PHP Version: 5.1.6 OS: FreeBSD 6
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: roel at qsp dot nl
New email:
PHP Version: OS:

 

 [2006-09-29 14:31 UTC] roel at qsp dot nl
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 <roel@bouwman.net>

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.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-10-01 21:00 UTC] iliaa@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Dec 21 16:01:28 2024 UTC