|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2004-07-15 13:00 UTC] tony2001@php.net
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Mon Oct 27 11:00:01 2025 UTC |
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);