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 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
From d4214cde2bd6f80d06497b274e56f0b91a4daee1 Mon Sep 17 00:00:00 2001
From: Madelyn Olson <madelyneolson@gmail.com>
Date: Wed, 2 Oct 2024 13:11:08 -0700
Subject: 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>
---
deps/lua/src/lua_bit.c | 1 +
src/acl.c | 2 +-
src/util.c | 9 ++++++---
tests/unit/acl-v2.tcl | 5 +++++
tests/unit/keyspace.tcl | 6 ++++++
tests/unit/scripting.tcl | 6 ++++++
6 files changed, 25 insertions(+), 4 deletions(-)
diff --git a/deps/lua/src/lua_bit.c b/deps/lua/src/lua_bit.c
index 9f83b8594..7e43faea4 100644
--- a/deps/lua/src/lua_bit.c
+++ b/deps/lua/src/lua_bit.c
@@ -132,6 +132,7 @@ static int bit_tohex(lua_State *L)
const char *hexdigits = "0123456789abcdef";
char buf[8];
int i;
+ if (n == INT32_MIN) n = INT32_MIN+1;
if (n < 0) { n = -n; hexdigits = "0123456789ABCDEF"; }
if (n > 8) n = 8;
for (i = (int)n; --i >= 0; ) { buf[i] = hexdigits[b & 15]; b >>= 4; }
diff --git a/src/acl.c b/src/acl.c
index 6d86093ca..6b53d901c 100644
--- a/src/acl.c
+++ b/src/acl.c
@@ -1036,7 +1036,7 @@ int ACLSetSelector(aclSelector *selector, const char* op, size_t oplen) {
flags |= ACL_READ_PERMISSION;
} else if (toupper(op[offset]) == 'W' && !(flags & ACL_WRITE_PERMISSION)) {
flags |= ACL_WRITE_PERMISSION;
- } else if (op[offset] == '~') {
+ } else if (op[offset] == '~' && flags) {
offset++;
break;
} else {
diff --git a/src/util.c b/src/util.c
index 8ce2c5fca..3a4c9b037 100644
--- a/src/util.c
+++ b/src/util.c
@@ -51,8 +51,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 '*':
@@ -64,7 +67,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 */
@@ -186,7 +189,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/acl-v2.tcl b/tests/unit/acl-v2.tcl
index d836f9cb8..114fadec3 100644
--- a/tests/unit/acl-v2.tcl
+++ b/tests/unit/acl-v2.tcl
@@ -107,6 +107,11 @@ start_server {tags {"acl external:skip"}} {
assert_match "*NOPERM*keys*" $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} {
r ACL SETUSER key-permission-RW-selector on nopass "(%R~read* +@all)" "(%W~write* +@all)"
$r2 auth key-permission-RW-selector password
diff --git a/tests/unit/keyspace.tcl b/tests/unit/keyspace.tcl
index 437f71fa1..988389fcf 100644
--- a/tests/unit/keyspace.tcl
+++ b/tests/unit/keyspace.tcl
@@ -495,4 +495,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]
+ } {}
}
diff --git a/tests/unit/scripting.tcl b/tests/unit/scripting.tcl
index 4b65131bf..cdc6dc448 100644
--- a/tests/unit/scripting.tcl
+++ b/tests/unit/scripting.tcl
@@ -590,6 +590,12 @@ start_server {tags {"scripting"}} {
set e
} {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} {
set decr_if_gt {
local current
--
2.30.2
|