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

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