Redis 6.2.5 widens bit offsets on 32-bit builds
Redis 6.2.5 fixes a 32-bit BITFIELD overflow and related bit-operation arithmetic. The patch distinguishes a position measured in bits from the memory size needed to store its bytes.
A position measured in bits needs a larger numeric range than the byte offset of the same position. Redis 6.2.5 repairs arithmetic that failed to preserve that distinction on 32-bit builds. The security consequence concerns BITFIELD, while the patch also widens related calculations in other bitmap commands. The implementation change is about units and integer width as well as allocation.
The 6.2 release notes date 6.2.5 to July 21. The tagged notes classify its urgency as security-related for affected authenticated connections on 32-bit versions, and moderate otherwise. That platform restriction is part of the event's meaning. It should not become a claim that every 64-bit deployment has the same vulnerability.
I have used Redis since its early releases, and bit operations are a useful example of its compact data model. The command interface deals in logical fields and positions, while the implementation must translate them into bytes. A type suitable for the final byte allocation is not automatically suitable for every intermediate bit position.
The advisory identifies overflow in the bit offset
The July 21 project advisory identifies CVE-2021-32761. It says specially crafted bit commands can overflow the bit offset on 32-bit Redis, potentially corrupting the heap, disclosing heap contents or permitting remote code execution. It names 6.2.5, 6.0.15 and 5.0.13 as patched versions.
The advisory supplies a mitigation of preventing use of BITFIELD, with ACLs available for that restriction in Redis 6.0 and later. This guidance concerns access to the affected operation. It does not imply that merely authenticating the caller validates the offset arithmetic. The release's urgency statement explicitly identifies authenticated client connections as the relevant exposure.
The 6.2.4-to-6.2.5 changes show the correction across the shared bit-operation implementation. The helper that parses a bit offset now writes it into uint64_t instead of size_t. Callers in GETBIT, SETBIT and the bitfield implementation use the wider representation too.
That distinction matters on a platform where size_t is 32 bits. The parsed logical position must survive until the implementation converts it into a byte location. Narrowing too early can change which memory the operation addresses. The patch preserves a larger range for the bit offset while retaining byte-sized addressing where the implementation actually needs it.
Shared helpers carry the representation through callers
The string-lookup helper for bit commands also changes its maximum-bit parameter to uint64_t. Inside it, shifting right by three obtains the byte position. This makes the unit conversion visible at the point where storage is considered. It avoids using the machine's allocation-size type as the representation for the original logical bit count.
The bitfield code widens both its parsed offset and the highest write offset. Its read path also uses a wider byte-position temporary while checking source bounds. These edits are related because preserving width only in the parser would still leave later narrowing points. The caller chain needs compatible representations for the value it transports.
Other bitmap calculations receive similar attention. redisPopcount changes its result and accumulator from size_t to long long. redisBitpos changes its result type and position accumulator from long to long long. Counting set bits can produce a result larger than the corresponding byte count, so the output's unit has its own range requirement.
The BITPOS path also widens values before converting byte counts and skipped-byte offsets into bits. These conversions contribute to the position returned to the client. Their correction matters to results as well as memory addressing. The patch is therefore broader than a single declaration inside BITFIELD.
I find this breadth useful when reading the repair. A shared representation can carry the same mistaken assumption into several commands. The release notes name the related bit operations, and the diff shows which shared helpers and local variables changed. That supplies a more concrete account than attributing every symptom to a generic allocator problem.
Reply-type fixes affect clients independently
The maintenance release also changes several replies. For RESP3, ZPOPMAX and ZPOPMIN with a count return nested arrays instead of the previous flat form. The notes explain the intended shape by reference to ZRANGE. A client decoder depends on that structure even when the underlying selected members remain the same.
For absent keys, HRANDFIELD and ZRANDMEMBER now return an empty array instead of a null array in the affected forms. ZRANGESTORE with a missing source returns zero instead of an empty array. These corrections distinguish a query-shaped result from the count returned by a store operation.
Such changes deserve a separate explanation from the security patch. A 64-bit deployment outside the stated BITFIELD vulnerability can still encounter a corrected reply shape. The moderate urgency for other users is consistent with a release that contains functional repairs in addition to its platform-specific security correction.
The release also fixes EXEC behavior when a watched key expires and prevents SINTERSTORE from deleting the destination when a source has the wrong type. These are command-semantics corrections with observable state consequences. They remain relevant without broadening the security advisory's platform scope.
Two other fixes concern newly added 6.2 behavior. A CLIENT UNPAUSE crash occurs with threaded I/O enabled, while XTRIM and XADD using LIMIT can delete more entries than the specified limit. The former has a configuration prerequisite. The latter concerns respecting a command argument during stream trimming. These descriptions identify why a user can need the maintenance update even when the server uses a 64-bit binary and the security advisory's narrower condition does not apply.
For the bitmap issue, the patch's concrete change is to preserve bit positions and counts in wider types across shared helpers and their callers. Byte conversion then occurs where required by storage access. The release simultaneously corrects client-visible reply structures, including the distinction between an empty range result and the zero count returned by a store command.