Fix possible crash due to OOM panic on invalid command (#13380)

getKeysUsingKeySpece had the range check AFTER the allocation, of the
keys buffer, which could lead to an OOM panic when invalid arguments are
provided, leading to an overflow.
The allocated memory is only used after the range check, so there's no
risk of buffer overrun.
The OOM panic can happen on 32bit builds, or 64 builds running on
systems with less than 4GB of RAM, and is reachable via the COMMAND
GETKEYSANDFLAGS, and ACL key name validation.
This commit is contained in:
Oran Agra 2024-07-01 09:04:20 +03:00 committed by GitHub
parent a9267137ee
commit 69b7137d32
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 9 additions and 5 deletions

View File

@ -2131,7 +2131,7 @@ int64_t getAllKeySpecsFlags(struct redisCommand *cmd, int inv) {
* found in other valid keyspecs.
*/
int getKeysUsingKeySpecs(struct redisCommand *cmd, robj **argv, int argc, int search_flags, getKeysResult *result) {
int j, i, last, first, step;
long j, i, last, first, step;
keyReference *keys;
serverAssert(result->numkeys == 0); /* caller should initialize or reset it */
@ -2191,20 +2191,20 @@ int getKeysUsingKeySpecs(struct redisCommand *cmd, robj **argv, int argc, int se
}
first += spec->fk.keynum.firstkey;
last = first + (int)numkeys-1;
last = first + (long)numkeys-1;
} else {
/* unknown spec */
goto invalid_spec;
}
int count = ((last - first)+1);
keys = getKeysPrepareResult(result, result->numkeys + count);
/* First or last is out of bounds, which indicates a syntax error */
if (last >= argc || last < first || first >= argc) {
goto invalid_spec;
}
int count = ((last - first)+1);
keys = getKeysPrepareResult(result, result->numkeys + count);
for (i = first; i <= last; i += step) {
if (i >= argc || i < first) {
/* Modules commands, and standard commands with a not fixed number

View File

@ -133,6 +133,10 @@ start_server {tags {"introspection"}} {
assert_equal {{k1 {RO access}} {k2 {OW update}}} [r command getkeysandflags sort k1 store k2]
}
test {COMMAND GETKEYSANDFLAGS invalid args} {
assert_error "ERR Invalid arguments*" {r command getkeysandflags ZINTERSTORE zz 1443677133621497600 asdf}
}
test {COMMAND GETKEYS MEMORY USAGE} {
assert_equal {key} [r command getkeys memory usage key]
}