Apply security fixes for CVEs (#1113)

Apply the security fixes for the release.

(CVE-2024-31449) Lua library commands may lead to stack overflow and
potential RCE.
(CVE-2024-31227) Potential Denial-of-service due to malformed ACL
selectors.
(CVE-2024-31228) Potential Denial-of-service due to unbounded pattern
matching.

---------

Signed-off-by: Madelyn Olson <madelyneolson@gmail.com>
This commit is contained in:
Madelyn Olson 2024-10-02 13:11:08 -07:00 committed by GitHub
parent 44a7c35d31
commit 357191acb9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 32 additions and 4 deletions

View File

@ -25,6 +25,13 @@ Bug fixes
* Resolved issues in replicationSetPrimary where the primary node's IP/port * Resolved issues in replicationSetPrimary where the primary node's IP/port
updates were not correctly handled in the cluster gossip section. (#965) updates were not correctly handled in the cluster gossip section. (#965)
Security fixes
==============
* (CVE-2024-31449) Lua library commands may lead to stack overflow and potential RCE.
* (CVE-2024-31227) Potential Denial-of-service due to malformed ACL selectors.
* (CVE-2024-31228) Potential Denial-of-service due to unbounded pattern matching.
================================================================================ ================================================================================
Valkey 7.2.6 GA - Released Tue 30 July 2024 Valkey 7.2.6 GA - Released Tue 30 July 2024
================================================================================ ================================================================================

View File

@ -132,6 +132,7 @@ static int bit_tohex(lua_State *L)
const char *hexdigits = "0123456789abcdef"; const char *hexdigits = "0123456789abcdef";
char buf[8]; char buf[8];
int i; int i;
if (n == INT32_MIN) n = INT32_MIN+1;
if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; } if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; }
if (n > 8) n = 8; if (n > 8) n = 8;
for (i = (int)n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; } for (i = (int)n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; }

View File

@ -1051,7 +1051,7 @@ int ACLSetSelector(aclSelector *selector, const char* op, size_t oplen) {
flags |= ACL_READ_PERMISSION; flags |= ACL_READ_PERMISSION;
} else if (toupper(op[offset]) == 'W' && !(flags & ACL_WRITE_PERMISSION)) { } else if (toupper(op[offset]) == 'W' && !(flags & ACL_WRITE_PERMISSION)) {
flags |= ACL_WRITE_PERMISSION; flags |= ACL_WRITE_PERMISSION;
} else if (op[offset] == '~') { } else if (op[offset] == '~' && flags) {
offset++; offset++;
break; break;
} else { } else {

View File

@ -54,8 +54,11 @@
/* Glob-style pattern matching. */ /* Glob-style pattern matching. */
static int stringmatchlen_impl(const char *pattern, int patternLen, 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) { while(patternLen && stringLen) {
switch(pattern[0]) { switch(pattern[0]) {
case '*': case '*':
@ -67,7 +70,7 @@ static int stringmatchlen_impl(const char *pattern, int patternLen,
return 1; /* match */ return 1; /* match */
while(stringLen) { while(stringLen) {
if (stringmatchlen_impl(pattern+1, patternLen-1, if (stringmatchlen_impl(pattern+1, patternLen-1,
string, stringLen, nocase, skipLongerMatches)) string, stringLen, nocase, skipLongerMatches, nesting+1))
return 1; /* match */ return 1; /* match */
if (*skipLongerMatches) if (*skipLongerMatches)
return 0; /* no match */ return 0; /* no match */
@ -189,7 +192,7 @@ static int stringmatchlen_impl(const char *pattern, int patternLen,
int stringmatchlen(const char *pattern, int patternLen, int stringmatchlen(const char *pattern, int patternLen,
const char *string, int stringLen, int nocase) { const char *string, int stringLen, int nocase) {
int skipLongerMatches = 0; 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) { int stringmatch(const char *pattern, const char *string, int nocase) {

View File

@ -116,6 +116,11 @@ start_server {tags {"acl external:skip"}} {
assert_match "*NOPERM*key*" $err assert_match "*NOPERM*key*" $err
} }
test {Validate read and write permissions format} {
catch {r ACL SETUSER key-permission-RW %~} err
set err
} {ERR Error in ACL SETUSER modifier '%~': Syntax error}
test {Test separate read and write permissions on different selectors are not additive} { test {Test separate read and write permissions on different selectors are not additive} {
r ACL SETUSER key-permission-RW-selector on nopass "(%R~read* +@all)" "(%W~write* +@all)" r ACL SETUSER key-permission-RW-selector on nopass "(%R~read* +@all)" "(%W~write* +@all)"
$r2 auth key-permission-RW-selector password $r2 auth key-permission-RW-selector password

View File

@ -499,4 +499,10 @@ foreach {type large} [array get largevalue] {
r SET aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 1 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" 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]
} {}
} }

View File

@ -641,6 +641,12 @@ start_server {tags {"scripting"}} {
set e set e
} {ERR *Attempt to modify a readonly table*} } {ERR *Attempt to modify a readonly table*}
test {lua bit.tohex bug} {
set res [run_script {return bit.tohex(65535, -2147483648)} 0]
r ping
set res
} {0000FFFF}
test {Test an example script DECR_IF_GT} { test {Test an example script DECR_IF_GT} {
set decr_if_gt { set decr_if_gt {
local current local current