Prevent LCS from allocating temp memory over proto-max-bulk-len (#9817)

LCS can allocate immense amount of memory (sizes of two inputs multiplied by each other).
In the past this caused some possible security issues due to overflows, which we solved
and also added use of `trymalloc` to return "Insufficient memory" instead of OOM panic zmalloc.

But in case overcommit is enabled, it could be that we won't get the OOM panic, and zmalloc
will succeed, and then we can get OOM killed by the kernel.

The solution here is to prevent LCS from allocating transient memory that's bigger than
`proto-max-bulk-len` config.
This config is not directly related to transient memory, but using a hard coded value ad well as
introducing a specific config seems wrong.

This comes to solve an error in the corrupt-dump-fuzzer test that started in the daily CI see #9799
This commit is contained in:
Oran Agra 2021-11-21 14:30:20 +02:00 committed by GitHub
parent d4e7ffb38c
commit 1417648469
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 2 deletions

View File

@ -800,10 +800,15 @@ void lcsCommand(client *c) {
unsigned long long lcssize = (unsigned long long)(alen+1)*(blen+1); /* Can't overflow due to the size limits above. */
unsigned long long lcsalloc = lcssize * sizeof(uint32_t);
uint32_t *lcs = NULL;
if (lcsalloc < SIZE_MAX && lcsalloc / lcssize == sizeof(uint32_t))
if (lcsalloc < SIZE_MAX && lcsalloc / lcssize == sizeof(uint32_t)) {
if (lcsalloc > (size_t)server.proto_max_bulk_len) {
addReplyError(c, "Insufficient memory, transient memory for LCS exceeds proto-max-bulk-len");
goto cleanup;
}
lcs = ztrymalloc(lcsalloc);
}
if (!lcs) {
addReplyError(c, "Insufficient memory");
addReplyError(c, "Insufficient memory, failed allocating transient memory for LCS");
goto cleanup;
}

View File

@ -732,5 +732,14 @@ test {corrupt payload: fuzzer findings - stream double free listpack when insert
}
}
test {corrupt payload: fuzzer findings - LCS OOM} {
start_server [list overrides [list loglevel verbose use-exit-on-panic yes crash-memcheck-enabled no] ] {
r SETRANGE _int 423324 1450173551
catch {r LCS _int _int} err
assert_match "*Insufficient memory*" $err
r ping
}
}
} ;# tags