summaryrefslogtreecommitdiff
path: root/src/networking.c
diff options
context:
space:
mode:
authorOran Agra <oran@redislabs.com>2021-10-04 12:10:31 +0300
committerGitHub <noreply@github.com>2021-10-04 12:10:31 +0300
commitfba15850e5c31666e4c3560a3be7fd034fa7e2b6 (patch)
treec0e13871ecb0301013a1e267c63e2ef686e9cff0 /src/networking.c
parent0215324a66af949be39b34be2d55143232c1cb71 (diff)
downloadredis-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.c17
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;