diff options
author | Oran Agra <oran@redislabs.com> | 2021-10-04 12:10:31 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-04 12:10:31 +0300 |
commit | fba15850e5c31666e4c3560a3be7fd034fa7e2b6 (patch) | |
tree | c0e13871ecb0301013a1e267c63e2ef686e9cff0 /src/networking.c | |
parent | 0215324a66af949be39b34be2d55143232c1cb71 (diff) | |
download | redis-fba15850e5c31666e4c3560a3be7fd034fa7e2b6.tar.gz |
Prevent unauthenticated client from easily consuming lots of memory (CVE-2021-32675) (#9588)
This change sets a low limit for multibulk and bulk length in the
protocol for unauthenticated connections, so that they can't easily
cause redis to allocate massive amounts of memory by sending just a few
characters on the network.
The new limits are 10 arguments of 16kb each (instead of 1m of 512mb)
Diffstat (limited to 'src/networking.c')
-rw-r--r-- | src/networking.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/src/networking.c b/src/networking.c index 8cfb0e331..9c1b46052 100644 --- a/src/networking.c +++ b/src/networking.c @@ -107,6 +107,15 @@ static void clientSetDefaultAuth(client *c) { !(c->user->flags & USER_FLAG_DISABLED); } +int authRequired(client *c) { + /* Check if the user is authenticated. This check is skipped in case + * the default user is flagged as "nopass" and is active. */ + int auth_required = (!(DefaultUser->flags & USER_FLAG_NOPASS) || + (DefaultUser->flags & USER_FLAG_DISABLED)) && + !c->authenticated; + return auth_required; +} + client *createClient(connection *conn) { client *c = zmalloc(sizeof(client)); @@ -1913,6 +1922,10 @@ int processMultibulkBuffer(client *c) { addReplyError(c,"Protocol error: invalid multibulk length"); setProtocolError("invalid mbulk count",c); return C_ERR; + } else if (ll > 10 && authRequired(c)) { + addReplyError(c, "Protocol error: unauthenticated multibulk length"); + setProtocolError("unauth mbulk count", c); + return C_ERR; } c->qb_pos = (newline-c->querybuf)+2; @@ -1961,6 +1974,10 @@ int processMultibulkBuffer(client *c) { addReplyError(c,"Protocol error: invalid bulk length"); setProtocolError("invalid bulk length",c); return C_ERR; + } else if (ll > 16384 && authRequired(c)) { + addReplyError(c, "Protocol error: unauthenticated bulk length"); + setProtocolError("unauth bulk length", c); + return C_ERR; } c->qb_pos = newline-c->querybuf+2; |