1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
From c8649f8e852d1dc388b5446e003bb0eefa33d61f Mon Sep 17 00:00:00 2001
From: Oran Agra <oran@redislabs.com>
Date: Wed, 2 Oct 2024 20:11:01 +0300
Subject: [PATCH] Prevent pattern matching abuse (CVE-2024-31228)
---
src/util.c | 9 ++++++---
tests/unit/keyspace.tcl | 6 ++++++
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/src/util.c b/src/util.c
index 861ef67..0f5e8e1 100644
--- a/src/util.c
+++ b/src/util.c
@@ -45,8 +45,11 @@
/* Glob-style pattern matching. */
static int stringmatchlen_impl(const char *pattern, int patternLen,
- const char *string, int stringLen, int nocase, int *skipLongerMatches)
+ const char *string, int stringLen, int nocase, int *skipLongerMatches, int nesting)
{
+ /* Protection against abusive patterns. */
+ if (nesting > 1000) return 0;
+
while(patternLen && stringLen) {
switch(pattern[0]) {
case '*':
@@ -58,7 +61,7 @@ static int stringmatchlen_impl(const char *pattern, int patternLen,
return 1; /* match */
while(stringLen) {
if (stringmatchlen_impl(pattern+1, patternLen-1,
- string, stringLen, nocase, skipLongerMatches))
+ string, stringLen, nocase, skipLongerMatches, nesting+1))
return 1; /* match */
if (*skipLongerMatches)
return 0; /* no match */
@@ -181,7 +184,7 @@ static int stringmatchlen_impl(const char *pattern, int patternLen,
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);
+ return stringmatchlen_impl(pattern,patternLen,string,stringLen,nocase,&skipLongerMatches,0);
}
int stringmatch(const char *pattern, const char *string, int nocase) {
diff --git a/tests/unit/keyspace.tcl b/tests/unit/keyspace.tcl
index 1617ac5..2217b29 100644
--- a/tests/unit/keyspace.tcl
+++ b/tests/unit/keyspace.tcl
@@ -278,4 +278,10 @@ start_server {tags {"keyspace"}} {
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"
} {}
+
+ test {Regression for pattern matching very long nested loops} {
+ r flushdb
+ r SET [string repeat "a" 50000] 1
+ r KEYS [string repeat "*?" 50000]
+ } {}
}
--
2.33.0
|