diff --git a/NEWS b/NEWS index 07653ef6a37f..24846881de96 100644 --- a/NEWS +++ b/NEWS @@ -31,6 +31,10 @@ PHP NEWS - OpenSSL: . Fix a bunch of memory leaks and crashes on edge cases. (ndossche) +- Random: + . Fixed bug GH-21731 (Random\Engine\Xoshiro256StarStar::__unserialize() + accepts all-zero state). (iliaal) + - SPL: . Fixed bug GH-21499 (RecursiveArrayIterator getChildren UAF after parent free). (Girgias) diff --git a/ext/random/engine_xoshiro256starstar.c b/ext/random/engine_xoshiro256starstar.c index 1a054362f065..b6ffd085c187 100644 --- a/ext/random/engine_xoshiro256starstar.c +++ b/ext/random/engine_xoshiro256starstar.c @@ -151,6 +151,12 @@ static bool unserialize(void *state, HashTable *data) } } + /* An all-zero state generates zero forever. The constructor rejects + * such a seed; reject it here for symmetry. */ + if (UNEXPECTED(s->state[0] == 0 && s->state[1] == 0 && s->state[2] == 0 && s->state[3] == 0)) { + return false; + } + return true; } diff --git a/ext/random/tests/02_engine/xoshiro256starstar_unserialize_zero_state.phpt b/ext/random/tests/02_engine/xoshiro256starstar_unserialize_zero_state.phpt new file mode 100644 index 000000000000..4a4d56cc210b --- /dev/null +++ b/ext/random/tests/02_engine/xoshiro256starstar_unserialize_zero_state.phpt @@ -0,0 +1,21 @@ +--TEST-- +GH-21731: Xoshiro256StarStar::__unserialize() must reject the all-zero state +--FILE-- +__unserialize([ + [], + ['0000000000000000', '0000000000000000', '0000000000000000', '0000000000000000'], + ]); + echo "FAIL: __unserialize() accepted zero state\n"; +} catch (\Exception $e) { + echo $e::class, ': ', $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +Exception: Invalid serialization data for Random\Engine\Xoshiro256StarStar object