Projects
Eulaceura:Factory
redis
_service:obs_scm:CVE-2021-21309.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:obs_scm:CVE-2021-21309.patch of Package redis
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
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