Memory safety / Buffer overflow

MEDIUM
redis/redis
Commit: 3627bbe12c55
Affected: <=8.6.2
2026-04-04 11:35 UTC

Description

The commit fixes memory handling and corruption risks in the Redis expression evaluator. Key changes: - exprCopyToken: For EXPR_TOKEN_SELECTOR, ensures that the token's start pointer is set to the allocated heap string, preventing use of an uninitialized or stale pointer and reducing risk of exposing or wandering memory access during string handling. - exprProcessOperator: On stack underflow during operator processing, explicitly frees the top_op token to avoid leaks and potential use-after-free scenarios. - exprCompile: When an operator token causes an error, frees the allocated op_token via exprFreeToken instead of RedisModule_Free, preventing mismatched memory management paths. - exprRun: Adds a bounds/sanity check before copying an object attribute name. The code now ensures t.str.len > 0 and t.str.len <= sizeof(item_name) before memcpying, and uses t.str.len-1 as the copy length with a null terminator. This prevents an underflow (e.g., when len == 0) that could lead to an oversized memcpy and memory corruption, and it constrains copies to the fixed 128-byte buffer. Overall, these changes shore up memory safety (allocation/freeing correctness and bounds checking) in the expression handling path. While the patch does not introduce or fix a specific CVE by name, it mitigates potential memory corruption and information leakage scenarios stemming from unsafe memcpy and pointer handling in expression evaluation.

Commit Details

Author: antirez

Date: 2025-02-25 08:43 UTC

Message:

Fixed a few memory handling/corruption bugs.

Triage Assessment

Vulnerability Type: Memory safety / Buffer overflow

Confidence: MEDIUM

Reasoning:

The patch contains memory safety improvements to expression handling (allocation/freeing correctness and bounds checking). These changes mitigate potential memory corruption crashes and incorrect memory access (e.g., unsafe memcpy with arbitrary lengths). While not tied to a specific CVE, they address memory safety vulnerabilities that could be exploited for crashes or information leakage.

Verification Assessment

Vulnerability Type: Memory safety / Buffer overflow

Confidence: MEDIUM

Affected Versions: <=8.6.2

Code Diff

diff --git a/expr.c b/expr.c index 714a1fadc1f..76f769b68d6 100644 --- a/expr.c +++ b/expr.c @@ -160,8 +160,8 @@ exprtoken *exprCopyToken(exprtoken *t) { t->token_type == EXPR_TOKEN_SELECTOR) { if (t->str.heapstr) { - printf("%d\n", t->token_type); new->str.heapstr = RedisModule_Strdup(t->str.heapstr); + new->str.start = new->str.heapstr; } } else if (t->token_type == EXPR_TOKEN_TUPLE) { new->tuple.ele = RedisModule_Alloc(sizeof(exprtoken*) * t->tuple.len); @@ -519,6 +519,7 @@ int exprProcessOperator(exprstate *es, exprtoken *op, int *stack_items, int *err int arity = exprGetOpArity(top_op->opcode); if (*stack_items < arity) { + exprFreeToken(top_op); if (errpos) *errpos = top_op->offset; return 1; } @@ -611,7 +612,7 @@ exprstate *exprCompile(char *expr, int *errpos) { if (token->token_type == EXPR_TOKEN_OP) { exprtoken *op_token = exprCopyToken(token); if (exprProcessOperator(es, op_token, &stack_items, errpos)) { - RedisModule_Free(op_token); + exprFreeToken(op_token); exprFree(es); return NULL; } @@ -724,7 +725,7 @@ int exprRun(exprstate *es, char *json, size_t json_len) { } if (parsed_json) { char item_name[128]; - if (t->str.len <= sizeof(item_name)) { + if (t.str.len > 0 && t->str.len <= sizeof(item_name)) { memcpy(item_name,t->str.start+1,t->str.len-1); item_name[t->str.len-1] = 0; attrib = cJSON_GetObjectItem(parsed_json,item_name);
← Back to Alerts View on GitHub →