You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
70 lines
2.7 KiB
70 lines
2.7 KiB
From 71be97294abf3657710a044157ebbc8a21489da3 Mon Sep 17 00:00:00 2001
|
|
From: Oran Agra <oran@redislabs.com>
|
|
Date: Wed, 9 Jun 2021 17:31:39 +0300
|
|
Subject: [PATCH] Prevent unauthenticated client from easily consuming lots of
|
|
memory (CVE-2021-32675)
|
|
|
|
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)
|
|
|
|
(cherry picked from commit 3d221e81f3b680543e34942579af190b049ff283)
|
|
---
|
|
src/networking.c | 8 ++++++++
|
|
tests/unit/auth.tcl | 16 ++++++++++++++++
|
|
2 files changed, 24 insertions(+)
|
|
|
|
diff --git a/src/networking.c b/src/networking.c
|
|
index bfaded9b4d0..2b8588094d2 100644
|
|
--- a/src/networking.c
|
|
+++ b/src/networking.c
|
|
@@ -1309,6 +1309,10 @@ int processMultibulkBuffer(client *c) {
|
|
addReplyError(c,"Protocol error: invalid multibulk length");
|
|
setProtocolError("invalid mbulk count",c);
|
|
return C_ERR;
|
|
+ } else if (ll > 10 && server.requirepass && !c->authenticated) {
|
|
+ addReplyError(c, "Protocol error: unauthenticated multibulk length");
|
|
+ setProtocolError("unauth mbulk count", c);
|
|
+ return C_ERR;
|
|
}
|
|
|
|
c->qb_pos = (newline-c->querybuf)+2;
|
|
@@ -1354,6 +1358,10 @@ int processMultibulkBuffer(client *c) {
|
|
addReplyError(c,"Protocol error: invalid bulk length");
|
|
setProtocolError("invalid bulk length",c);
|
|
return C_ERR;
|
|
+ } else if (ll > 16384 && server.requirepass && !c->authenticated) {
|
|
+ addReplyError(c, "Protocol error: unauthenticated bulk length");
|
|
+ setProtocolError("unauth bulk length", c);
|
|
+ return C_ERR;
|
|
}
|
|
|
|
c->qb_pos = newline-c->querybuf+2;
|
|
diff --git a/tests/unit/auth.tcl b/tests/unit/auth.tcl
|
|
index 633cda95c92..f5da728e845 100644
|
|
--- a/tests/unit/auth.tcl
|
|
+++ b/tests/unit/auth.tcl
|
|
@@ -24,4 +24,20 @@ start_server {tags {"auth"} overrides {requirepass foobar}} {
|
|
r set foo 100
|
|
r incr foo
|
|
} {101}
|
|
+
|
|
+ test {For unauthenticated clients multibulk and bulk length are limited} {
|
|
+ set rr [redis [srv "host"] [srv "port"] 0]
|
|
+ $rr write "*100\r\n"
|
|
+ $rr flush
|
|
+ catch {[$rr read]} e
|
|
+ assert_match {*unauthenticated multibulk length*} $e
|
|
+ $rr close
|
|
+
|
|
+ set rr [redis [srv "host"] [srv "port"] 0]
|
|
+ $rr write "*1\r\n\$100000000\r\n"
|
|
+ $rr flush
|
|
+ catch {[$rr read]} e
|
|
+ assert_match {*unauthenticated bulk length*} $e
|
|
+ $rr close
|
|
+ }
|
|
}
|