php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #15044 Signal 11/access violation w/user registered session handler
Submitted: 2002-01-15 06:34 UTC Modified: 2002-06-18 19:15 UTC
From: charles dot haley at ac dot aup dot fr Assigned:
Status: Not a bug Package: Session related
PHP Version: 4.1.1 OS: Redhat 7.1/Windows ME
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: charles dot haley at ac dot aup dot fr
New email:
PHP Version: OS:

 

 [2002-01-15 06:34 UTC] charles dot haley at ac dot aup dot fr
PHP crashes reliably under windows ME and semi-reliably under Linux when using user-registered session-handling w/mysql, or at least using *my* session-handling code.  The problem begins if there are no session variables defined; that is the session_read function returns an empty string.  As far as I can tell, in this case the $_SESSION array is created in some strange state and the session_write function is never called.  Under Windows ME, the CGI process dies with an access violation near the end of processing; the page is 1/2 displayed.  Under Linux, the apache/php process segfaults around 25% of the time.  This behavior did not occur using php.4.0.6 and earlier.

There is some interaction with register_globals.  If I turned register_globals on, the frequency of the crash under linux was halved, but php under windows continued to crash reliably.  I was unable to find any pattern under linux.

The work-around is to never return '' from the session_read function.  After making this change, the crashes under Windows and Linux stopped and joy was returned to my world.

It is, of course, possible that I am misusing the session-handling feature.  If this is the case, please let me know and accept my apologies for what becomes a semi-bogus bug report.

Note that the script consisting of the session registration code included below and "phpinfo()" provoked the crash.
============
Configuration information: Windows
- Windows ME
- apache 1.3.20 binary release
- PHP 4.1.1 full binary release, configured as CGI
============
Configuration information: Linux.
- Redhat 7.1, updated.
- Apache 1.3.22 (also tried with 1.3.19)
- PHP 4.1.1, compiled as module (also tried 4.1.0)
============
php configure script:
./configure \
    --with-mysql=/usr \
    --enable-sysvsem \
    --enable-sysvshm \
    --enable-debugger \
    --enable-force-cgi-redirect \
    --disable-short-tags \
    --prefix=/home/php \
    --with-config-file-path=/home/php \
    --with-exec-dir=/home/php/bin \
    --enable-discard-path \
    --with-oci8=/home/oracle/app/oracle/product/8.0.5 \
    --with-apache=/usr/src/local/apache_1.3.22 \
    --with-ldap
============
apache configure script:
./configure --prefix=/usr \
 --with-layout=RedHat \
 --enable-module=all \
 --enable-shared=max \
 --disable-rule=WANTHSREGEX \
 --disable-module=auth_dbm \
 --enable-suexec \
 --suexec-caller=web \
 --suexec-docroot=/home/httpd/html \
 --suexec-logfile=/var/log/httpd/suexec.log \
 --suexec-userdir=public_web \
 --suexec-uidmin=500 \
 --suexec-gidmin=100 \
 --suexec-safepath=/usr/local/bin:/usr/bin:/bin \
 --activate-module=src/modules/php4/libphp4.a \
 --activate-module=src/modules/auth_mysql/libauth_mysql.a
============
My session-handling code:

include_once "open_db.php";
function mySession_open ($save_path, $session_name) {
	if (isset ($_COOKIE['AUPcatalog'])) {
		session_id($_COOKIE['AUPcatalog']);
	}
	return true;
}

function mySession_close() {
    return true;
}

function mySession_read ($key) {
	$sess = mysql_query ("select ps_vars from phpsessions where ps_sessionid = '$key'") or die (mysql_error());
	$v = mysql_fetch_array ($sess, MYSQL_ASSOC);
	if (!isset ($v['ps_vars']) || $v['ps_vars'] == '')
		return "F1F2F3|i:1;";	// must return something, apparently!
	return $v['ps_vars'];
}

function mySession_write ($key, $val) {
	mysql_query ("update phpsessions set ps_vars='$val', ps_lasttouched=UNIX_TIMESTAMP() where ps_sessionid = '$key'") or die (mysql_error());
	if (mysql_affected_rows() == 0) {
		mysql_query ("insert phpsessions set ps_vars='$val', ps_lasttouched=UNIX_TIMESTAMP(), ps_sessionid = '$key'");
	}
	return true;
}

function mySession_destroy ($key) {
	mysql_query ("delete from mycourses where mc_sessionid = '$key'");
	mysql_query ("delete from phpsessions where ps_sessionid = '$key'");
    return true;
}

function mySession_gc ($maxlifetime) {
	$sessions = mysql_query ("select ps_sessionid from phpsessions where ps_lasttouched < UNIX_TIMESTAMP() - $maxlifetime") or die (mysql_error());
	while ($sess = mysql_fetch_array($sessions, MYSQL_ASSOC)) {
		if ($sess['ps_sessionid'] == session_id()) {
			continue;
		}
		mySession_destroy ($sess['ps_sessionid']);
	}
    return true;
}

session_module_name ("user");
session_set_save_handler ("mySession_open", "mySession_close", "mySession_read", "mySession_write", "mySession_destroy", "mySession_gc");
 
session_name ("AUPcatalog");
session_start();
============

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-01-15 08:11 UTC] yohgaki@php.net
That's strange. read should treat '' well.
That is your serializer?


BTW, don't use die(), but return error (false) except for read.
 [2002-01-15 08:34 UTC] charles dot haley at ac dot aup dot fr
Thanks for the "die" tip.

I am not supplying a serializer, but instead am depending on the one supplied by default.  My assumption, which seems to be born out in practice, is that "write" is given already-serialized data and that "read" is expected to return this same serialized data.  The issue is, of course, that the first "read" doesn't have anything to return since "write" hasn't yet been called.

I can't pretend to understand what is happening.  What is certain is that the behavior changed from 4.0.6 to 4.1.0.  What seems to be true is that ensuring that read gives back *something* in correct serialized format corrects the problem.  I suspect a relationship with constructing the new $_SESSION array, but can't prove it.
 [2002-01-15 20:01 UTC] yohgaki@php.net
FYI, I don't have problem with user save handler with PostgreSQL at all.
Is MySQL return NULL for null fields? Then you MUST NOT return NULL, but return ''.

Are you having the same proboem with RH7.1 and windows?
Could you send backtrace from RH7.1, it may help.
 [2002-01-16 02:32 UTC] charles dot haley at ac dot aup dot fr
> Is MySQL return NULL for null fields? Then you 
> MUST NOT return NULL, but return ''.

You have identified the problem.  The fields in my database are defined as "NOT NULL".  However, the record may not exist (this is certainly true the first time around) causing mysql_fetch to return a non-array value.  My code would then subscript this non-array and return an unset value, which is equivalent to returning a NULL field.  Yet again I am caught by the "almost-equivalence" of unset values and '' values.  

I checked out the idea by changing my read function to return '' if the row doesn't exist or the DB field is unset.  The problem went away.

It is interesting to note that the use of the non-existent index did *not* result in the normal warning (I run with all warnings turned on).  In this case mysql_fetch returned a boolean type (false), which was then subscripted.  No warning about incompatible types or a non-existent index was given.  Probably some sort of warning should be generated when idiots like me do such silly things.

> Are you having the same proboem with RH7.1 and 
> windows?

Yes, and the solution derived from your suggestion works on both.

As far as I am concerned, this issue is closed.  I would suggest, though, that whatever calls session_read be a bit more defensive and protect itself against unset return values.

Thank you.
 [2002-01-16 03:02 UTC] yohgaki@php.net
I'll make this one a duplicate since there is bug report for this.
 [2002-06-18 19:15 UTC] sniper@php.net
..just add your comments to the existing report(s).

 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun May 05 19:01:31 2024 UTC