Projects
Eulaceura:Factory
redis
_service:obs_scm:CVE-2022-36021.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:CVE-2022-36021.patch of Package redis
From dcbfcb916ca1a269b3feef86ee86835294758f84 Mon Sep 17 00:00:00 2001 From: Oran Agra <oran@redislabs.com> Date: Tue, 28 Feb 2023 15:15:26 +0200 Subject: [PATCH] String pattern matching had exponential time complexity on pathological patterns (CVE-2022-36021) (#11858) 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. Co-authored-by: Tom Levy <tomlevy93@gmail.com> --- 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 d33f4522a507..26d92b92290e 100644 --- a/src/util.c +++ b/src/util.c @@ -44,8 +44,8 @@ #include "sha1.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]) { @@ -57,12 +57,24 @@ 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. */ return 0; /* no match */ break; case '?': @@ -166,10 +178,17 @@ 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); } + /* Convert a string representing an amount of memory into the number of * bytes, so for instance memtoll("1Gb") will return 1073741824 that is * (1024*1024*1024). diff --git a/tests/unit/keyspace.tcl b/tests/unit/keyspace.tcl index b173e0efcacc..43690d06b321 100644 --- a/tests/unit/keyspace.tcl +++ b/tests/unit/keyspace.tcl @@ -493,4 +493,10 @@ foreach {type large} [array get largevalue] { 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" + } {} }
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2