-
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Description
Symfony version(s) affected
4.4-7.x
Description
Since switching to AWS' serverless redis implementation, we've come across some redis scan cursors with values greater than PHP_MAX_INT
.
When using phpredis
the next bit of the doClear
function might result in an integer overflow situation:
(Taken from RedisTrait.php
at branch 6.4
, but the implementation hasn't changed much since 4.4)
$cursor = null;
do {
$keys = $host->scan($cursor, $pattern, 1000);
if (isset($keys[1]) && \is_array($keys[1])) {
$cursor = $keys[0];
$keys = $keys[1];
}
if ($keys) {
if ($prefixLen) {
foreach ($keys as $i => $key) {
$keys[$i] = substr($key, $prefixLen);
}
}
$this->doDelete($keys);
}
} while ($cursor = (int) $cursor);
afaik php has no userland types that support values that exceed PHP_MAX_INT
Running the scan algorithm using the redis-cli
as client, I see the following:
127.0.0.1:56381> scan 0 match finc-9754a4310b0* count 1000
1) "9286422431638129152"
2) (empty array)
127.0.0.1:56381> scan 9286422431638129152 match finc-9754a4310b0* count 1000
1) "9286422431638550784"
2) 1) "finc-9754a4310b0:project_4518"
2) "finc-9754a4310b0:project_4182"
3) "finc-9754a4310b0:project_4477"
4) "finc-9754a4310b0:project_525"
5) "finc-9754a4310b0:project_874"
6) "finc-9754a4310b0:project_2878"
127.0.0.1:56381> scan 9286422431638550784 match finc-9754a4310b0* count 1000
1) "9286422431638337280"
2) 1) "finc-9754a4310b0:project_2785"
2) "finc-9754a4310b0:project_3752"
3) "finc-9754a4310b0:project_2676"
4) "finc-9754a4310b0:project_3592"
5) "finc-9754a4310b0:project_2881"
6) "finc-9754a4310b0:person_3791"
7) "finc-9754a4310b0:project_1682"
8) "finc-9754a4310b0:project_94"
9) "finc-9754a4310b0:project_1002"
10) "finc-9754a4310b0:FilterOptionsCache^18^Invoice_all"
Scouring the internet for related issues, the most relevant one seemed to be this one: phpredis/phpredis#2454
Attached are the PR's that fix part of the issue in the underlying implementation.
I believe by casting the cursor to string, we are triggering an overflow. This is supported by the fact that the doClear functions seems to have no effect whatsoever on our redis database.
How to reproduce
I don't understand redis well enough to be able to provide a reproducer for a redis database that yields these super high cursor values.
Possible Solution
I guess if we remove the cast to int, we might already be there.
Additional Context
No response