Code Review Bench PR #14227 - Fix HINCRBYFLOAT removes field expiration on replica#8
Conversation
🔍 CI failure analysis for 01bf0c0: All CI build jobs are failing due to an unused variable 'unused_flag' in src/t_hash.c:2244 causing a compilation error when -Werror flag is enabled.IssueAll CI build jobs across different platforms (CentOS, Debian, Ubuntu, macOS, 32-bit) are failing with the same compilation error. Root CauseIn the file int unused_flag = 0;This variable is declared but never used in the function. When Redis builds with the DetailsThis appears to be leftover code from the PR changes that modified the The error occurs in the All build jobs are affected because Redis enforces strict compilation with Code Review 🚫 Blocked 0 resolved / 3 findingsCritical stack buffer overflow in HPEXPIREAT argv array (declared size 5, writes 6 elements), plus a memory leak from missing decrRefCount on the created expireat string object. Both must be fixed before merge. 🚨 Bug: Stack buffer overflow: argv[5] written to array of size 5The The HPEXPIREAT command requires 6 arguments: Suggested fix
|
| Auto-apply | Compact |
|
|
Was this helpful? React with 👍 / 👎 | Gitar
| /* Propagate HSET */ | ||
| alsoPropagate(c->db->id, c->argv, c->argc, PROPAGATE_AOF|PROPAGATE_REPL); | ||
| /* Propagate HPEXPIREAT */ | ||
| robj *argv[5]; |
There was a problem hiding this comment.
🚨 Bug: Stack buffer overflow: argv[5] written to array of size 5
The argv array is declared as robj *argv[5] (indices 0–4), but the code writes to argv[5] (6 elements, indices 0–5). This is a stack buffer overflow that will corrupt adjacent stack memory, leading to undefined behavior — potentially crashes, data corruption, or exploitable security vulnerabilities.
The HPEXPIREAT command requires 6 arguments: HPEXPIREAT key timestamp FIELDS 1 fieldname, so the array must be sized accordingly.
Was this helpful? React with 👍 / 👎
| robj *argv[5]; | |
| robj *argv[6]; | |
- Apply suggested fix
| robj *argv[5]; | ||
| argv[0] = shared.hpexpireat; | ||
| argv[1] = c->argv[1]; | ||
| argv[2] = createStringObjectFromLongLong(expireat); |
There was a problem hiding this comment.
⚠️ Bug: Memory leak: missing decrRefCount for created expireat object
argv[2] is created via createStringObjectFromLongLong(expireat) which allocates a new object with refcount 1. alsoPropagate() then increments the refcount to 2 (it copies and incr's). After the call, the local reference is never decremented, so the object will have a refcount that's 1 too high and will never be freed.
The existing pattern in t_stream.c (around the XGROUP SETID propagation) correctly calls decrRefCount() after alsoPropagate() for dynamically created argv objects. The same pattern should be followed here.
Was this helpful? React with 👍 / 👎
| argv[2] = createStringObjectFromLongLong(expireat); | |
| alsoPropagate(c->db->id, argv, 6, PROPAGATE_AOF|PROPAGATE_REPL); | |
| decrRefCount(argv[2]); | |
- Apply suggested fix
Benchmark PR for Gitar evaluation
Original PR: agentic-review-benchmarks#8
Fix HINCRBYFLOAT removes field expiration on replica