SHA256
1
0
forked from pool/redis

Accepting request 1068515 from home:vlefebvre:branches:server:database

Fix CVE-2022-36021 (bsc#1208790) & Fix CVE-2023-25155 (bsc#1208793)

OBS-URL: https://build.opensuse.org/request/show/1068515
OBS-URL: https://build.opensuse.org/package/show/server:database/redis?expand=0&rev=218
This commit is contained in:
Martin Pluskal 2023-03-02 13:49:31 +00:00 committed by Git OBS Bridge
parent 580642cadf
commit 7616b2211a
4 changed files with 217 additions and 0 deletions

View File

@ -0,0 +1,115 @@
From 2a2a582e7cd99ba3b531336b8bd41df2b566e619 Mon Sep 17 00:00:00 2001
From: Oran Agra <oran@redislabs.com>
Date: Tue, 21 Feb 2023 15:16:13 +0200
Subject: [PATCH] Integer Overflow in RAND commands can lead to assertion
(CVE-2023-25155)
Issue happens when passing a negative long value that greater than
the max positive value that the long can store.
---
src/t_hash.c | 4 ++--
src/t_set.c | 2 +-
src/t_zset.c | 4 ++--
tests/unit/type/hash.tcl | 2 ++
tests/unit/type/set.tcl | 5 +++++
tests/unit/type/zset.tcl | 2 ++
6 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/src/t_hash.c b/src/t_hash.c
index 754315080..f4ddccc62 100644
--- a/src/t_hash.c
+++ b/src/t_hash.c
@@ -1120,13 +1120,13 @@ void hrandfieldCommand(client *c) {
listpackEntry ele;
if (c->argc >= 3) {
- if (getLongFromObjectOrReply(c,c->argv[2],&l,NULL) != C_OK) return;
+ if (getRangeLongFromObjectOrReply(c,c->argv[2],-LONG_MAX,LONG_MAX,&l,NULL) != C_OK) return;
if (c->argc > 4 || (c->argc == 4 && strcasecmp(c->argv[3]->ptr,"withvalues"))) {
addReplyErrorObject(c,shared.syntaxerr);
return;
} else if (c->argc == 4) {
withvalues = 1;
- if (l < LONG_MIN/2 || l > LONG_MAX/2) {
+ if (l < -LONG_MAX/2 || l > LONG_MAX/2) {
addReplyError(c,"value is out of range");
return;
}
diff --git a/src/t_set.c b/src/t_set.c
index b01729f0a..dff66d052 100644
--- a/src/t_set.c
+++ b/src/t_set.c
@@ -665,7 +665,7 @@ void srandmemberWithCountCommand(client *c) {
dict *d;
- if (getLongFromObjectOrReply(c,c->argv[2],&l,NULL) != C_OK) return;
+ if (getRangeLongFromObjectOrReply(c,c->argv[2],-LONG_MAX,LONG_MAX,&l,NULL) != C_OK) return;
if (l >= 0) {
count = (unsigned long) l;
} else {
diff --git a/src/t_zset.c b/src/t_zset.c
index 3cd2d2438..a9b5031ea 100644
--- a/src/t_zset.c
+++ b/src/t_zset.c
@@ -4289,13 +4289,13 @@ void zrandmemberCommand(client *c) {
listpackEntry ele;
if (c->argc >= 3) {
- if (getLongFromObjectOrReply(c,c->argv[2],&l,NULL) != C_OK) return;
+ if (getRangeLongFromObjectOrReply(c,c->argv[2],-LONG_MAX,LONG_MAX,&l,NULL) != C_OK) return;
if (c->argc > 4 || (c->argc == 4 && strcasecmp(c->argv[3]->ptr,"withscores"))) {
addReplyErrorObject(c,shared.syntaxerr);
return;
} else if (c->argc == 4) {
withscores = 1;
- if (l < LONG_MIN/2 || l > LONG_MAX/2) {
+ if (l < -LONG_MAX/2 || l > LONG_MAX/2) {
addReplyError(c,"value is out of range");
return;
}
diff --git a/tests/unit/type/hash.tcl b/tests/unit/type/hash.tcl
index fcb42e81e..4edb146ed 100644
--- a/tests/unit/type/hash.tcl
+++ b/tests/unit/type/hash.tcl
@@ -74,6 +74,8 @@ start_server {tags {"hash"}} {
test "HRANDFIELD count overflow" {
r hmset myhash a 1
assert_error {*value is out of range*} {r hrandfield myhash -9223372036854770000 withvalues}
+ assert_error {*value is out of range*} {r hrandfield myhash -9223372036854775808 withvalues}
+ assert_error {*value is out of range*} {r hrandfield myhash -9223372036854775808}
} {}
test "HRANDFIELD with <count> against non existing key" {
diff --git a/tests/unit/type/set.tcl b/tests/unit/type/set.tcl
index 30b6dc5d7..5257dccea 100644
--- a/tests/unit/type/set.tcl
+++ b/tests/unit/type/set.tcl
@@ -645,6 +645,11 @@ start_server {
r srandmember nonexisting_key 100
} {}
+ test "SRANDMEMBER count overflow" {
+ r sadd myset a
+ assert_error {*value is out of range*} {r srandmember myset -9223372036854775808}
+ } {}
+
# Make sure we can distinguish between an empty array and a null response
r readraw 1
diff --git a/tests/unit/type/zset.tcl b/tests/unit/type/zset.tcl
index a758aee46..88c0bcb43 100644
--- a/tests/unit/type/zset.tcl
+++ b/tests/unit/type/zset.tcl
@@ -2303,6 +2303,8 @@ start_server {tags {"zset"}} {
test "ZRANDMEMBER count overflow" {
r zadd myzset 0 a
assert_error {*value is out of range*} {r zrandmember myzset -9223372036854770000 withscores}
+ assert_error {*value is out of range*} {r zrandmember myzset -9223372036854775808 withscores}
+ assert_error {*value is out of range*} {r zrandmember myzset -9223372036854775808}
} {}
# Make sure we can distinguish between an empty array and a null response
--
2.35.3

View File

@ -0,0 +1,88 @@
From 0825552565e5fdab2e87950579c4f0bedded3e3c Mon Sep 17 00:00:00 2001
From: Tom Levy <tomlevy93@gmail.com>
Date: Tue, 21 Feb 2023 15:14:30 +0200
Subject: [PATCH] String pattern matching had exponential time complexity on
pathological patterns (CVE-2022-36021)
Authenticated users can use string matching commands with a
specially crafted pattern to trigger a denial-of-service attack on Redis,
causing it to hang and consume 100% CPU time.
---
src/util.c | 27 +++++++++++++++++++++++----
tests/unit/keyspace.tcl | 6 ++++++
2 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/src/util.c b/src/util.c
index e1524b5e3..8ce2c5fca 100644
--- a/src/util.c
+++ b/src/util.c
@@ -50,8 +50,8 @@
#include "config.h"
/* Glob-style pattern matching. */
-int stringmatchlen(const char *pattern, int patternLen,
- const char *string, int stringLen, int nocase)
+static int stringmatchlen_impl(const char *pattern, int patternLen,
+ const char *string, int stringLen, int nocase, int *skipLongerMatches)
{
while(patternLen && stringLen) {
switch(pattern[0]) {
@@ -63,12 +63,25 @@ int stringmatchlen(const char *pattern, int patternLen,
if (patternLen == 1)
return 1; /* match */
while(stringLen) {
- if (stringmatchlen(pattern+1, patternLen-1,
- string, stringLen, nocase))
+ if (stringmatchlen_impl(pattern+1, patternLen-1,
+ string, stringLen, nocase, skipLongerMatches))
return 1; /* match */
+ if (*skipLongerMatches)
+ return 0; /* no match */
string++;
stringLen--;
}
+ /* There was no match for the rest of the pattern starting
+ * from anywhere in the rest of the string. If there were
+ * any '*' earlier in the pattern, we can terminate the
+ * search early without trying to match them to longer
+ * substrings. This is because a longer match for the
+ * earlier part of the pattern would require the rest of the
+ * pattern to match starting later in the string, and we
+ * have just determined that there is no match for the rest
+ * of the pattern starting from anywhere in the current
+ * string. */
+ *skipLongerMatches = 1;
return 0; /* no match */
break;
case '?':
@@ -170,6 +183,12 @@ int stringmatchlen(const char *pattern, int patternLen,
return 0;
}
+int stringmatchlen(const char *pattern, int patternLen,
+ const char *string, int stringLen, int nocase) {
+ int skipLongerMatches = 0;
+ return stringmatchlen_impl(pattern,patternLen,string,stringLen,nocase,&skipLongerMatches);
+}
+
int stringmatch(const char *pattern, const char *string, int nocase) {
return stringmatchlen(pattern,strlen(pattern),string,strlen(string),nocase);
}
diff --git a/tests/unit/keyspace.tcl b/tests/unit/keyspace.tcl
index f5f971140..437f71fa1 100644
--- a/tests/unit/keyspace.tcl
+++ b/tests/unit/keyspace.tcl
@@ -489,4 +489,10 @@ start_server {tags {"keyspace"}} {
r keys *
r keys *
} {dlskeriewrioeuwqoirueioqwrueoqwrueqw}
+
+ test {Regression for pattern matching long nested loops} {
+ r flushdb
+ r SET aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1
+ r KEYS "a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*a*b"
+ } {}
}
--
2.35.3

View File

@ -1,3 +1,11 @@
-------------------------------------------------------------------
Wed Mar 1 16:29:28 UTC 2023 - Valentin Lefebvre <valentin.lefebvre@suse.com>
- Fix CVE-2022-36021 (bsc#1208790 CVE-2022-36021)
* String-pattern-matching-had-exponential-time-complex.patch
- Fix CVE-2023-25155 (bsc#1208793 CVE-2023-25155)
* Integer-Overflow-in-RAND-commands-can-lead-to-assert.patch
-------------------------------------------------------------------
Mon Jan 16 21:00:00 UTC 2023 - Andreas Stieger <andreas.stieger@gmx.de>

View File

@ -40,6 +40,10 @@ Source10: https://raw.githubusercontent.com/redis/redis-hashes/master/READ
Patch0: %{name}-conf.patch
Patch3: reproducible.patch
Patch4: ppc-atomic.patch
# PATCH-FIX-UPSTREAM -- based on commit 0825552 (bsc#1208790 CVE-2022-36021)
Patch5: String-pattern-matching-had-exponential-time-complex.patch
# PATCH-FIX-UPSTREAM -- based on commit 2a2a582 (bsc#1208793 CVE-2023-25155)
Patch6: Integer-Overflow-in-RAND-commands-can-lead-to-assert.patch
BuildRequires: jemalloc-devel
BuildRequires: libopenssl-devel >= 1.1.1
BuildRequires: pkgconfig
@ -67,6 +71,8 @@ echo "`grep -F %{name}-%{version}.tar.gz %{SOURCE10} | cut -d' ' -f4` %{SOURCE0
%patch0
%patch3 -p1
%patch4 -p1
%patch5 -p1
%patch6 -p1
%build
export HOST=OBS # for reproducible builds