summaryrefslogtreecommitdiff
path: root/src/t_string.c
diff options
context:
space:
mode:
authorOran Agra <oran@redislabs.com>2023-01-16 13:49:30 +0200
committerGitHub <noreply@github.com>2023-01-16 13:49:30 +0200
commit1ec82e6e97e1db06a72ca505f9fbf6b981f31ef7 (patch)
tree6d15d2f79f93f70f671bdcab84b38f85b7a3f171 /src/t_string.c
parent395d801a2d978c3bb3139498c51825c393ae4450 (diff)
downloadredis-1ec82e6e97e1db06a72ca505f9fbf6b981f31ef7.tar.gz
Avoid integer overflows in SETRANGE and SORT (CVE-2022-35977) (#11720)
Authenticated users issuing specially crafted SETRANGE and SORT(_RO) commands can trigger an integer overflow, resulting with Redis attempting to allocate impossible amounts of memory and abort with an OOM panic.
Diffstat (limited to 'src/t_string.c')
-rw-r--r--src/t_string.c17
1 files changed, 11 insertions, 6 deletions
diff --git a/src/t_string.c b/src/t_string.c
index 125f8ee86..6208d6a85 100644
--- a/src/t_string.c
+++ b/src/t_string.c
@@ -37,8 +37,14 @@ int getGenericCommand(client *c);
* String Commands
*----------------------------------------------------------------------------*/
-static int checkStringLength(client *c, long long size) {
- if (!mustObeyClient(c) && size > server.proto_max_bulk_len) {
+static int checkStringLength(client *c, long long size, long long append) {
+ if (mustObeyClient(c))
+ return C_OK;
+ /* 'uint64_t' cast is there just to prevent undefined behavior on overflow */
+ long long total = (uint64_t)size + append;
+ /* Test configured max-bulk-len represending a limit of the biggest string object,
+ * and also test for overflow. */
+ if (total > server.proto_max_bulk_len || total < size || total < append) {
addReplyError(c,"string exceeds maximum allowed size (proto-max-bulk-len)");
return C_ERR;
}
@@ -454,7 +460,7 @@ void setrangeCommand(client *c) {
}
/* Return when the resulting string exceeds allowed size */
- if (checkStringLength(c,offset+sdslen(value)) != C_OK)
+ if (checkStringLength(c,offset,sdslen(value)) != C_OK)
return;
o = createObject(OBJ_STRING,sdsnewlen(NULL, offset+sdslen(value)));
@@ -474,7 +480,7 @@ void setrangeCommand(client *c) {
}
/* Return when the resulting string exceeds allowed size */
- if (checkStringLength(c,offset+sdslen(value)) != C_OK)
+ if (checkStringLength(c,offset,sdslen(value)) != C_OK)
return;
/* Create a copy when the object is shared or encoded. */
@@ -703,8 +709,7 @@ void appendCommand(client *c) {
/* "append" is an argument, so always an sds */
append = c->argv[2];
- totlen = stringObjectLen(o)+sdslen(append->ptr);
- if (checkStringLength(c,totlen) != C_OK)
+ if (checkStringLength(c,stringObjectLen(o),sdslen(append->ptr)) != C_OK)
return;
/* Append the value */