php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #29012 Potential race during first connection
Submitted: 2004-07-05 07:52 UTC Modified: 2004-07-15 13:00 UTC
From: cjbj at hotmail dot com Assigned:
Status: Closed Package: OCI8 related
PHP Version: 5.0.0RC3 OS: n/a
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: cjbj at hotmail dot com
New email:
PHP Version: OS:

 

 [2004-07-05 07:52 UTC] cjbj at hotmail dot com
Description:
------------
The mutex locking in _oci_open_session() in
php-5.0.0RC3/ext/oci8/oci.c at about line 2676 may allow a
possible race.  This was discovered from code inspection so I could be
wrong.

The current code is:

   if (zend_ts_hash_find(persistent_sessions, hashed_details.c, hashed_details.len+1, (void **) &session_list) != SUCCESS) {
       zend_llist tmp;
       /* first session, set up a session list */
       zend_llist_init(&tmp, sizeof(oci_session), (llist_dtor_func_t) _session_pcleanup, 1);
       zend_ts_hash_update(persistent_sessions, hashed_details.c, hashed_details.len+1, &tmp, sizeof(zend_llist), (void **) &session_list);
   } else {
       mutex_lock(mx_lock);

       /* session list found, search for an idle session or an already opened session by the current thread */
       session = zend_llist_get_first(session_list);
       while ((session != NULL) && session->thread && (session->thread != thread_id())) {
	   session = zend_llist_get_next(session_list);
       }

       if (session != NULL) {
	   /* mark session as busy */
	   session->thread = thread_id();
       }
       mutex_unlock(mx_lock);
   }


I don't understand why there is no locking around the
zend_llist_init() or even zend_ts_hash_find() calls.  If multiple
users log in at once then does zend_ts_hash_find() guarentee to return
SUCCESS for only one thread?  If not, a suggested change is:

   mutex_lock(mx_lock);
   if (zend_ts_hash_find(persistent_sessions, hashed_details.c, hashed_details.len+1, (void **) &session_list) != SUCCESS) {
       zend_llist tmp;
       /* first session, set up a session list */
       zend_llist_init(&tmp, sizeof(oci_session), (llist_dtor_func_t) _session_pcleanup, 1);
       zend_ts_hash_update(persistent_sessions, hashed_details.c, hashed_details.len+1, &tmp, sizeof(zend_llist), (void **) &session_list);
   } else {

       /* session list found, search for an idle session or an already opened session by the current thread */
       session = zend_llist_get_first(session_list);
       while ((session != NULL) && session->thread && (session->thread != thread_id())) {
	   session = zend_llist_get_next(session_list);
       }

       if (session != NULL) {
	   /* mark session as busy */
	   session->thread = thread_id();
       }
   }
   mutex_unlock(mx_lock);



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-07-15 13:00 UTC] tony2001@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-2025 The PHP Group
All rights reserved.
Last updated: Tue Jul 15 01:01:35 2025 UTC