SessionLockHeldDuringBlockingCall
warning native off by defaultGroup: Probable bugs
Detect a known blocking sleep/usleep or network operation while an active session with a known locking handler remains owned by the scope.
Example
php
<?php
ini_set('session.save_handler', 'files'); session_start(); sleep(8); session_write_close();Reported:
- line 2: Release the session lock before blocking when safe.
Detection
- Report a known blocking sleep/usleep or network operation while an active session with a known locking handler remains owned by the scope.
- Resolve builtin calls and named arguments before checking the contract. Project-local callees are considered only when their bodies or immutable summaries establish the required facts. The default is disabled; enable only when the stated intent matches the application.
- The session is active when the last session operation reaching the blocking call is a
session_startthat keeps the session open: it has no options, or its options are a literal array with constant string keys whoseread_and_closeentry is absent or known to be falsy. - The handler is known to lock only when the last handler selection written before that
session_startis an unconditionalini_set/ini_alterofsession.save_handlerto the literal'files'. Only writes in the same scope are considered. - For flow-dependent conditions, require a reachable source-to-use path with no intervening invalidation. Unknown calls, ambiguous aliases, recursion or analysis-budget exhaustion cannot establish definite facts.
Exceptions (no report)
- Nonlocking handlers, earlier successful session_write_close, required atomic session work and unknown handler configuration are excluded.
session_startwithread_and_closeenabled, or with options that cannot be read statically (a non-literal value, a spread, an unpacked or non-string key, an unknownread_and_closevalue): the lock may already be released.- After the
'files'selection and beforesession_start: another or unknown value written tosession.save_handler, an ini write whose option name is unknown,ini_restoreof that option,session_set_save_handler, orsession_module_namecalled with an argument, whether conditional or not. The handler in effect is then unknown. - A handler selection written after
session_startproves nothing about the session already open. - Unresolved targets, incomplete required facts, suppressed findings and PHP versions lacking the referenced API or language feature produce no report. User declarations shadowing builtin names are not builtin contracts.
Fix
No automatic fix: early close may discard later writes or break atomic session behavior.
PHP versions
Apply only on PHP versions supporting the referenced APIs and syntax (within PHP 5.3–8.5). Builtin behavior and argument contracts follow the configured PHP version. Extension-specific calls require resolved extension API symbols; do not treat same-named application functions as extension calls.
Options
None. Enable or disable this rule through normal rule configuration.
Configure
In custos.json:
json
{
"rules": {
"SessionLockHeldDuringBlockingCall": {
"enabled": true
}
}
}Suppress
Before the statement or declaration (or the first statement of the file):
php
// @custos-ignore SessionLockHeldDuringBlockingCall