!24 fix CVE-2021-21039
From: @wangxiao65 Reviewed-by: @zhanghua1831,@small_leek Signed-off-by: @small_leek
This commit is contained in:
commit
752011564d
150
CVE-2021-21309.patch
Normal file
150
CVE-2021-21309.patch
Normal file
@ -0,0 +1,150 @@
|
||||
From 48f04a82a0ac542341fb644a4cfbebadd5c59a33 Mon Sep 17 00:00:00 2001
|
||||
From: Yossi Gottlieb <yossigo@gmail.com>
|
||||
Date: Mon, 22 Feb 2021 15:41:32 +0200
|
||||
Subject: [PATCH] Fix integer overflow (CVE-2021-21309). (#8522)
|
||||
|
||||
On 32-bit systems, setting the proto-max-bulk-len config parameter to a high value may result with integer overflow and a subsequent heap overflow when parsing an input bulk (CVE-2021-21309).
|
||||
|
||||
This fix has two parts:
|
||||
|
||||
Set a reasonable limit to the config parameter.
|
||||
Add additional checks to prevent the problem in other potential but unknown code paths.
|
||||
|
||||
(cherry picked from commit d32f2e9999ce003bad0bd2c3bca29f64dcce4433)
|
||||
|
||||
Fix MSVR reported issue.
|
||||
---
|
||||
src/config.c | 16 ++++++++--------
|
||||
src/sds.c | 3 +++
|
||||
src/zmalloc.c | 10 ++++++++++
|
||||
3 files changed, 21 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/config.c b/src/config.c
|
||||
index 5f22442ecc5..0814768b9d9 100644
|
||||
--- a/src/config.c
|
||||
+++ b/src/config.c
|
||||
@@ -817,10 +817,10 @@ void loadServerConfig(char *filename, ch
|
||||
if (max != LLONG_MAX && ll > max) goto badfmt; \
|
||||
_var = ll;
|
||||
|
||||
-#define config_set_memory_field(_name,_var) \
|
||||
+#define config_set_memory_field(_name,_var,min,max) \
|
||||
} else if (!strcasecmp(c->argv[2]->ptr,_name)) { \
|
||||
ll = memtoll(o->ptr,&err); \
|
||||
- if (err || ll < 0) goto badfmt; \
|
||||
+ if (err || ll < (long long) (min) || ll > (long long) (max)) goto badfmt; \
|
||||
_var = ll;
|
||||
|
||||
#define config_set_enum_field(_name,_var,_enumvar) \
|
||||
@@ -1063,7 +1063,7 @@ void configSetCommand(client *c) {
|
||||
} config_set_numerical_field(
|
||||
"active-defrag-threshold-upper",server.active_defrag_threshold_upper,0,1000) {
|
||||
} config_set_memory_field(
|
||||
- "active-defrag-ignore-bytes",server.active_defrag_ignore_bytes) {
|
||||
+ "active-defrag-ignore-bytes",server.active_defrag_ignore_bytes,0,LONG_MAX) {
|
||||
} config_set_numerical_field(
|
||||
"active-defrag-cycle-min",server.active_defrag_cycle_min,1,99) {
|
||||
} config_set_numerical_field(
|
||||
@@ -1139,7 +1139,7 @@ void configSetCommand(client *c) {
|
||||
|
||||
/* Memory fields.
|
||||
* config_set_memory_field(name,var) */
|
||||
- } config_set_memory_field("maxmemory",server.maxmemory) {
|
||||
+ } config_set_memory_field("maxmemory",server.maxmemory,0,LONG_MAX) {
|
||||
if (server.maxmemory) {
|
||||
if (server.maxmemory < zmalloc_used_memory()) {
|
||||
serverLog(LL_WARNING,"WARNING: the new maxmemory value set via CONFIG SET is smaller than the current memory usage. This will result in keys eviction and/or inability to accept new write commands depending on the maxmemory-policy.");
|
||||
@@ -1147,12 +1147,12 @@ void configSetCommand(client *c) {
|
||||
freeMemoryIfNeeded();
|
||||
}
|
||||
} config_set_memory_field(
|
||||
- "proto-max-bulk-len",server.proto_max_bulk_len) {
|
||||
+ "proto-max-bulk-len",server.proto_max_bulk_len,1024*1024,LONG_MAX/2) {
|
||||
} config_set_memory_field(
|
||||
- "client-query-buffer-limit",server.client_max_querybuf_len) {
|
||||
- } config_set_memory_field("repl-backlog-size",ll) {
|
||||
+ "client-query-buffer-limit",server.client_max_querybuf_len,0,LONG_MAX) {
|
||||
+ } config_set_memory_field("repl-backlog-size",ll,0,LONG_MAX) {
|
||||
resizeReplicationBacklog(ll);
|
||||
- } config_set_memory_field("auto-aof-rewrite-min-size",ll) {
|
||||
+ } config_set_memory_field("auto-aof-rewrite-min-size",ll,0,LONG_MAX) {
|
||||
server.aof_rewrite_min_size = ll;
|
||||
|
||||
/* Enumeration fields.
|
||||
diff --git a/src/sds.c b/src/sds.c
|
||||
index cd60946bdd3..12c9da356d9 100644
|
||||
--- a/src/sds.c
|
||||
+++ b/src/sds.c
|
||||
@@ -91,6 +91,7 @@ sds sdsnewlen(const void *init, size_t initlen) {
|
||||
int hdrlen = sdsHdrSize(type);
|
||||
unsigned char *fp; /* flags pointer. */
|
||||
|
||||
+ assert(hdrlen+initlen+1 > initlen); /* Catch size_t overflow */
|
||||
sh = s_malloc(hdrlen+initlen+1);
|
||||
if (!init)
|
||||
memset(sh, 0, hdrlen+initlen+1);
|
||||
@@ -207,6 +208,7 @@ sds sdsMakeRoomFor(sds s, size_t addlen) {
|
||||
len = sdslen(s);
|
||||
sh = (char*)s-sdsHdrSize(oldtype);
|
||||
newlen = (len+addlen);
|
||||
+ assert(newlen > len); /* Catch size_t overflow */
|
||||
if (newlen < SDS_MAX_PREALLOC)
|
||||
newlen *= 2;
|
||||
else
|
||||
@@ -220,6 +222,7 @@ sds sdsMakeRoomFor(sds s, size_t addlen) {
|
||||
if (type == SDS_TYPE_5) type = SDS_TYPE_8;
|
||||
|
||||
hdrlen = sdsHdrSize(type);
|
||||
+ assert(hdrlen+newlen+1 > len); /* Catch size_t overflow */
|
||||
if (oldtype==type) {
|
||||
newsh = s_realloc(sh, hdrlen+newlen+1);
|
||||
if (newsh == NULL) return NULL;
|
||||
diff --git a/src/zmalloc.c b/src/zmalloc.c
|
||||
index 972db79d7ab..29e68180f0d 100644
|
||||
--- a/src/zmalloc.c
|
||||
+++ b/src/zmalloc.c
|
||||
@@ -55,6 +55,12 @@ void zlibc_free(void *ptr) {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
+#if PREFIX_SIZE > 0
|
||||
+#define ASSERT_NO_SIZE_OVERFLOW(sz) assert((sz) + PREFIX_SIZE > (sz))
|
||||
+#else
|
||||
+#define ASSERT_NO_SIZE_OVERFLOW(sz)
|
||||
+#endif
|
||||
+
|
||||
/* Explicitly override malloc/free etc when using tcmalloc. */
|
||||
#if defined(USE_TCMALLOC)
|
||||
#define malloc(size) tc_malloc(size)
|
||||
@@ -95,6 +101,7 @@ static void zmalloc_default_oom(size_t size) {
|
||||
static void (*zmalloc_oom_handler)(size_t) = zmalloc_default_oom;
|
||||
|
||||
void *zmalloc(size_t size) {
|
||||
+ ASSERT_NO_SIZE_OVERFLOW(size);
|
||||
void *ptr = malloc(size+PREFIX_SIZE);
|
||||
|
||||
if (!ptr) zmalloc_oom_handler(size);
|
||||
@@ -113,6 +120,7 @@ void *zmalloc(size_t size) {
|
||||
* Currently implemented only for jemalloc. Used for online defragmentation. */
|
||||
#ifdef HAVE_DEFRAG
|
||||
void *zmalloc_no_tcache(size_t size) {
|
||||
+ ASSERT_NO_SIZE_OVERFLOW(size);
|
||||
void *ptr = mallocx(size+PREFIX_SIZE, MALLOCX_TCACHE_NONE);
|
||||
if (!ptr) zmalloc_oom_handler(size);
|
||||
update_zmalloc_stat_alloc(zmalloc_size(ptr));
|
||||
@@ -127,6 +135,7 @@ void zfree_no_tcache(void *ptr) {
|
||||
#endif
|
||||
|
||||
void *zcalloc(size_t size) {
|
||||
+ ASSERT_NO_SIZE_OVERFLOW(size);
|
||||
void *ptr = calloc(1, size+PREFIX_SIZE);
|
||||
|
||||
if (!ptr) zmalloc_oom_handler(size);
|
||||
@@ -141,6 +150,7 @@ void *zcalloc(size_t size) {
|
||||
}
|
||||
|
||||
void *zrealloc(void *ptr, size_t size) {
|
||||
+ ASSERT_NO_SIZE_OVERFLOW(size);
|
||||
#ifndef HAVE_MALLOC_SIZE
|
||||
void *realptr;
|
||||
#endif
|
||||
@ -1,6 +1,6 @@
|
||||
Name: redis
|
||||
Version: 4.0.11
|
||||
Release: 12
|
||||
Release: 13
|
||||
Summary: A persistent key-value database
|
||||
License: BSD and MIT
|
||||
URL: https://redis.io
|
||||
@ -21,6 +21,7 @@ Patch0006: CVE-2019-10193.patch
|
||||
Patch0007: modify-aarch64-architecture-jemalloc-page-size-from-4k-to-64k.patch
|
||||
%endif
|
||||
Patch0008: huawei-deps-jemalloc-support-riscv.patch
|
||||
Patch0009: CVE-2021-21309.patch
|
||||
BuildRequires: systemd
|
||||
Requires: /bin/awk
|
||||
Requires: logrotate
|
||||
@ -91,6 +92,9 @@ exit 0
|
||||
%{_unitdir}/%{name}-sentinel.service
|
||||
|
||||
%changelog
|
||||
* Thu Mar 11 2021 wangxiao <wangxiao65@huawei.com> - 4.0.11-13
|
||||
- Fix CVE-2021-21309
|
||||
|
||||
* Wed Nov 11 2020 yangyanchao <yangyanchao6@huawei.com> - 4.0.11-12
|
||||
- enable dependency package jemalloc of redis to support riscv
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user