Skip to content

Commit cd7de3e

Browse files
committed
Fix GH-21731: Random\Engine\Xoshiro256StarStar::__unserialize() accepts all-zero state
The constructor rejects a seed that would leave the internal state all zero, because xoshiro256** with zero state produces 0 on every call forever. The unserialize callback didn't check the same invariant. A caller feeding a crafted serialized payload through __unserialize() ended up with a live engine that returned 0 from every operation. Match the constructor: reject the all-zero state from the unserialize callback too. The Mt19937-aliased __unserialize() wrapper turns the false return into the standard "Invalid serialization data" exception. Closes GH-21731
1 parent afded3d commit cd7de3e

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ PHP NEWS
3131
- OpenSSL:
3232
. Fix a bunch of memory leaks and crashes on edge cases. (ndossche)
3333

34+
- Random:
35+
. Fixed bug GH-21731 (Random\Engine\Xoshiro256StarStar::__unserialize()
36+
accepts all-zero state). (iliaal)
37+
3438
- SPL:
3539
. Fixed bug GH-21499 (RecursiveArrayIterator getChildren UAF after parent
3640
free). (Girgias)

ext/random/engine_xoshiro256starstar.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,12 @@ static bool unserialize(void *state, HashTable *data)
151151
}
152152
}
153153

154+
/* An all-zero state generates zero forever. The constructor rejects
155+
* such a seed; reject it here for symmetry. */
156+
if (UNEXPECTED(s->state[0] == 0 && s->state[1] == 0 && s->state[2] == 0 && s->state[3] == 0)) {
157+
return false;
158+
}
159+
154160
return true;
155161
}
156162

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
GH-21731: Xoshiro256StarStar::__unserialize() must reject the all-zero state
3+
--FILE--
4+
<?php declare(strict_types = 1);
5+
6+
use Random\Engine\Xoshiro256StarStar;
7+
8+
try {
9+
$engine = new Xoshiro256StarStar(42);
10+
$engine->__unserialize([
11+
[],
12+
['0000000000000000', '0000000000000000', '0000000000000000', '0000000000000000'],
13+
]);
14+
echo "FAIL: __unserialize() accepted zero state\n";
15+
} catch (\Exception $e) {
16+
echo $e::class, ': ', $e->getMessage(), "\n";
17+
}
18+
19+
?>
20+
--EXPECT--
21+
Exception: Invalid serialization data for Random\Engine\Xoshiro256StarStar object

0 commit comments

Comments
 (0)