From f7b1d0287d62ec9fac72bf14cf789e350d14e52b Mon Sep 17 00:00:00 2001 From: Oran Agra Date: Tue, 9 Jan 2024 13:51:56 +0200 Subject: [PATCH] Fix possible corruption in sdsResize (CVE-2023-41056) (#12924) #11766 introduced a bug in sdsResize where it could forget to update the sds type in the sds header and then cause an overflow in sdsalloc. it looks like the only implication of that is a possible assertion in HLL, but it's hard to rule out possible heap corruption issues with clientsCronResizeQueryBuffer --- src/sds.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/sds.c b/src/sds.c index f5383f90e..4ed792e5c 100644 --- a/src/sds.c +++ b/src/sds.c @@ -349,20 +349,22 @@ sds sdsResize(sds s, size_t size, int would_regrow) { * type. */ int use_realloc = (oldtype==type || (type < oldtype && type > SDS_TYPE_8)); size_t newlen = use_realloc ? oldhdrlen+size+1 : hdrlen+size+1; - int alloc_already_optimal = 0; - #if defined(USE_JEMALLOC) - /* je_nallocx returns the expected allocation size for the newlen. - * We aim to avoid calling realloc() when using Jemalloc if there is no - * change in the allocation size, as it incurs a cost even if the - * allocation size stays the same. */ - alloc_already_optimal = (je_nallocx(newlen, 0) == zmalloc_size(sh)); - #endif - if (use_realloc && !alloc_already_optimal) { - newsh = s_realloc(sh, newlen); - if (newsh == NULL) return NULL; - s = (char*)newsh+oldhdrlen; - } else if (!alloc_already_optimal) { + if (use_realloc) { + int alloc_already_optimal = 0; + #if defined(USE_JEMALLOC) + /* je_nallocx returns the expected allocation size for the newlen. + * We aim to avoid calling realloc() when using Jemalloc if there is no + * change in the allocation size, as it incurs a cost even if the + * allocation size stays the same. */ + alloc_already_optimal = (je_nallocx(newlen, 0) == zmalloc_size(sh)); + #endif + if (!alloc_already_optimal) { + newsh = s_realloc(sh, newlen); + if (newsh == NULL) return NULL; + s = (char*)newsh+oldhdrlen; + } + } else { newsh = s_malloc(newlen); if (newsh == NULL) return NULL; memcpy((char*)newsh+hdrlen, s, len);