Blame SOURCES/redis-CVE-2021-32675.patch

3a8238
From 71be97294abf3657710a044157ebbc8a21489da3 Mon Sep 17 00:00:00 2001
3a8238
From: Oran Agra <oran@redislabs.com>
3a8238
Date: Wed, 9 Jun 2021 17:31:39 +0300
3a8238
Subject: [PATCH] Prevent unauthenticated client from easily consuming lots of
3a8238
 memory (CVE-2021-32675)
3a8238
3a8238
This change sets a low limit for multibulk and bulk length in the
3a8238
protocol for unauthenticated connections, so that they can't easily
3a8238
cause redis to allocate massive amounts of memory by sending just a few
3a8238
characters on the network.
3a8238
The new limits are 10 arguments of 16kb each (instead of 1m of 512mb)
3a8238
3a8238
(cherry picked from commit 3d221e81f3b680543e34942579af190b049ff283)
3a8238
---
3a8238
 src/networking.c    |  8 ++++++++
3a8238
 tests/unit/auth.tcl | 16 ++++++++++++++++
3a8238
 2 files changed, 24 insertions(+)
3a8238
3a8238
diff --git a/src/networking.c b/src/networking.c
3a8238
index bfaded9b4d0..2b8588094d2 100644
3a8238
--- a/src/networking.c
3a8238
+++ b/src/networking.c
3a8238
@@ -1309,6 +1309,10 @@ int processMultibulkBuffer(client *c) {
3a8238
             addReplyError(c,"Protocol error: invalid multibulk length");
3a8238
             setProtocolError("invalid mbulk count",c);
3a8238
             return C_ERR;
3a8238
+        } else if (ll > 10 && server.requirepass && !c->authenticated) {
3a8238
+            addReplyError(c, "Protocol error: unauthenticated multibulk length");
3a8238
+            setProtocolError("unauth mbulk count", c);
3a8238
+            return C_ERR;
3a8238
         }
3a8238
 
3a8238
         c->qb_pos = (newline-c->querybuf)+2;
3a8238
@@ -1354,6 +1358,10 @@ int processMultibulkBuffer(client *c) {
3a8238
                 addReplyError(c,"Protocol error: invalid bulk length");
3a8238
                 setProtocolError("invalid bulk length",c);
3a8238
                 return C_ERR;
3a8238
+            } else if (ll > 16384 && server.requirepass && !c->authenticated) {
3a8238
+                addReplyError(c, "Protocol error: unauthenticated bulk length");
3a8238
+                setProtocolError("unauth bulk length", c);
3a8238
+                return C_ERR;
3a8238
             }
3a8238
 
3a8238
             c->qb_pos = newline-c->querybuf+2;
3a8238
diff --git a/tests/unit/auth.tcl b/tests/unit/auth.tcl
3a8238
index 633cda95c92..f5da728e845 100644
3a8238
--- a/tests/unit/auth.tcl
3a8238
+++ b/tests/unit/auth.tcl
3a8238
@@ -24,4 +24,20 @@ start_server {tags {"auth"} overrides {requirepass foobar}} {
3a8238
         r set foo 100
3a8238
         r incr foo
3a8238
     } {101}
3a8238
+
3a8238
+    test {For unauthenticated clients multibulk and bulk length are limited} {
3a8238
+        set rr [redis [srv "host"] [srv "port"] 0]
3a8238
+        $rr write "*100\r\n"
3a8238
+        $rr flush
3a8238
+        catch {[$rr read]} e
3a8238
+        assert_match {*unauthenticated multibulk length*} $e
3a8238
+        $rr close
3a8238
+
3a8238
+        set rr [redis [srv "host"] [srv "port"] 0]
3a8238
+        $rr write "*1\r\n\$100000000\r\n"
3a8238
+        $rr flush
3a8238
+        catch {[$rr read]} e
3a8238
+        assert_match {*unauthenticated bulk length*} $e
3a8238
+        $rr close
3a8238
+    }
3a8238
 }