Redis 6.0.9 removes an allocator size assumption
Redis 6.0.9 fixes a potential heap overflow on affected allocators and changes WATCH handling of expired keys. Both changes correct assumptions about state that other code relies on.
Knowing the requested size of an allocation is different from knowing that the allocator supplied extra usable bytes. Redis 6.0.9 removes an assumption that some allocation sizes could be rounded upward. On affected platforms, the resulting overestimate could lead to an out-of-bounds write. The release makes its security urgency conditional on the allocator in use.
The release notes date 6.0.9 to October 26, 2020. The tagged notes classify it as a security upgrade on affected platforms and moderate elsewhere. They identify allocators other than jemalloc or glibc malloc as the relevant case. That condition matters when reporting the scope of the problem.
I have used Redis since its release, and I value the care its implementation puts into memory management. This fix concerns a particularly important boundary. A size-reporting helper can become part of a caller's memory-safety reasoning, even when the helper also serves ordinary memory accounting.
The fallback stores the requested size
The fixed allocation wrapper has different paths depending on whether allocator size information is available. In the fallback path it allocates space for a prefix as well as the requested payload. The prefix stores the requested size, and the pointer returned to the caller advances past that header.
This arrangement gives Redis its own record of the requested allocation size. When the platform cannot report allocator sizing directly, the wrapper can recover the value by moving back from the caller's pointer to the prefix. Allocation, reallocation and freeing use that representation consistently within the fallback.
The prefix is not spare application capacity. It is storage reserved by the wrapper for its own bookkeeping. The helper that reports usable payload subtracts the prefix from the total size helper. That relationship makes it important that the total does not invent bytes beyond the allocation.
The previous implementation rounded the stored size upward to a multiple of the size of a C long. Its comment explicitly assumed that the underlying allocator padded every allocation to at least that boundary. The size returned to callers could therefore exceed the requested payload.
That may match the behaviour of some allocators, but it does not establish a general contract for the fallback path. A private expectation about implementation padding is insufficient if another supported allocator supplies a block without the assumed extra capacity. The wrapper's stored requested size remains the information it actually controls.
The fixed helper stops rounding upward
In 6.0.9 the fallback size helper reads the stored value and returns it with the prefix size. The rounding calculation disappears. The usable-size helper then subtracts the prefix, leaving the requested payload size.
This is a correction to what the helper claims. The wrapper does not need to prove that all allocators pad identically if it reports only the capacity represented by its own allocation request. Callers no longer receive the additional bytes inferred from the removed assumption.
The contemporaneous fix discussion says the overestimate led to an out-of-bounds write in at least one case, with a process crash and potential security consequences. Yossi Gottlieb credits Drew DeVault with reporting the problem and a different fix. The discussion explicitly excludes the common jemalloc and glibc cases from the disclosed impact.
That account supports a bounded security claim. It identifies an unsafe write under a particular allocation condition. It does not establish a universal remote-code-execution result or supply a reason to attach a later vulnerability classification to today's post.
The release's conditional urgency follows from that boundary. The version number identifies whether the fix is present, while the allocator determines whether the particular assumption is relevant to the build. Treating every installation as identical would lose the condition the maintainers put in the announcement.
Expiration now affects watched transactions
The patch also changes a client-visible consistency rule. Its tagged notes say WATCH no longer ignores expired keys for MULTI and EXEC. The corresponding change replaces a narrow tracking invalidation with the general modified-key signal in active expiration.
The updated test watches a key with a short lifetime, waits for expiration and then attempts a transaction containing PING. Its expected result changes from a successful PONG response to an aborted transaction. No application write is required between the watch and the execution for expiration to matter.
The transaction implementation marks clients watching a modified key with its dirty compare-and-set flag. That flag records that the watched condition no longer holds. Expiration now reaches that notification mechanism through the modified-key path.
This is relevant to any application using a watched expiring value as a precondition. A value disappearing is a state transition even when no client explicitly sends a deletion. The transaction mechanism needs to reflect that transition if the application expects the watch to protect the observed state.
The command can therefore abort under circumstances that an earlier release allowed to proceed. That is the intended behaviour change documented in the notes and test. An application needs to interpret the aborted execution as a failed precondition, separately from an ordinary command error within a completed transaction.
Other changes retain their own scope
The release also adds support for a rediss:// URI prefix in the command-line client's URL option. It fixes atomic handling of rewritten configuration files and adds an fsync after a replica receives a full RDB payload. These are separate changes with distinct operating consequences.
They do not alter the allocator condition attached to the security fix. A release can contain a narrowly affected memory-safety correction alongside broadly useful operational work. The notes preserve that distinction by giving affected platforms security urgency and other installations a moderate rating.
I find the allocation change useful because the corrected claim is visible in a few lines. The fallback now reports the requested payload through its stored header without rounding it into presumed capacity. The transaction change applies the same demand for accurate state at another level, making expiration notify clients whose execution depends on a watched key.