You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ext/random: Random\Engine\Xoshiro256StarStar::__unserialize() accepts all-zero state #21731
Random\Engine\Xoshiro256StarStar::__construct() rejects a seed that would leave the internal state all zero, because xoshiro256** with zero state produces 0 on every call forever:
if (UNEXPECTED(t[0] ==0&&t[1] ==0&&t[2] ==0&&t[3] ==0)) {
zend_argument_value_error(1, "must not consist entirely of NUL bytes");
RETURN_THROWS();
}
__unserialize() doesn't check the same invariant. If a caller feeds this payload through __unserialize(), the engine lands in the forbidden state, and everything downstream returns zero: generate(), Randomizer::getInt(), Randomizer::getBytes(), Randomizer::nextFloat(), and every other method that consumes the engine.
__unserialize() should reject the all-zero state the same way __construct() does. Returning false from the unserialize callback in engine_xoshiro256starstar.c is enough; the Mt19937-aliased __unserialize() wrapper turns that into the standard "Invalid serialization data for ... object" exception.
Without the guard, a bad serialized payload (hand-crafted, or round-tripped from an attacker-controlled source) produces a Randomizer that silently returns 0 from every method.
PHP Version
master (PHP 8.6.0-dev). The unserialize callback has shipped without the zero-state check since Xoshiro256StarStar landed, so 8.3, 8.4, and 8.5 are affected too.
Activity
Fix GH-21731: Random\Engine\Xoshiro256StarStar::__unserialize() accep…
Merge branch 'PHP-8.4' into PHP-8.5
Merge branch 'PHP-8.5'