January 20, 2023·4 min read·engineeringvalkeyredissecurity

Redis bounds command arithmetic in its January security fixes

Redis 7.0.8 fixes integer overflows in string, sorting, and random-member commands. The patches validate derived sizes before they reach allocation or reply construction.

A command argument can fit its declared integer type while the arithmetic performed with it exceeds a safe range. Redis's January security fixes address that distinction in several ordinary commands. The 7.0 release notes record 7.0.8 on January 16 with fixes for CVE-2022-35977 and CVE-2023-22458. The advisories published on January 20 explain how authenticated callers could use crafted arguments to terminate the server.

The two flaws concern different derived values. String and sorting operations could lead Redis to attempt impossible allocations. Random-member commands could produce reply arithmetic that triggered an assertion. Both demonstrate why parsing a number successfully is only the start of validating a command that derives resource sizes from it.

I have used Redis since its early releases, and its direct command model remains part of its appeal. That familiarity makes these patches worth reading closely. A short command name and a valid integer argument do not establish that every internal size calculation is safe.

String growth needs checked addition

The CVE-2022-35977 advisory identifies SETRANGE and SORT or SORT_RO. Authenticated callers could trigger integer overflow and drive Redis into an out-of-memory panic. The stated impact is process availability. The advisory does not describe a successful arbitrary-code-execution path.

The fixing commit changes the string-length checker to accept a current size and an appended size separately. Previously, callers could calculate a sum before passing it to the checker. If the addition itself overflowed, a later comparison against the configured maximum could inspect an already-invalid result.

The revised helper performs the addition using an unsigned cast to avoid undefined overflow behavior in that calculation. It then checks the resulting total against the configured maximum and against both inputs. A total smaller than an input indicates that the addition did not produce an acceptable growth size.

SETRANGE now passes the offset and supplied value length as separate inputs. The append path similarly passes the existing string length and appended value length separately. This moves the arithmetic into the helper that owns the safety check, instead of requiring every caller to calculate an unchecked candidate size first.

The important property is the order of operations. A maximum-length check is useful only if computing the length has not already violated the assumptions needed by the comparison. Centralizing the operands gives the checker enough information to detect the overflow condition.

Sorting limits are bounded by the collection

The same commit changes how sorting interprets its limit start and count. It bounds the start by the vector length and bounds the count before deriving the end position. The collection's actual size supplies a useful upper bound for that intermediate arithmetic.

This illustrates a different validation technique from checking a string-growth sum. Sorting cannot return more elements from the selected vector than the vector contains. Applying that fact before calculating the range reduces the opportunity for extreme input values to produce an invalid internal bound.

SORT_RO is part of the affected command set even though it is the read-only variant. Read-only describes whether the command modifies stored data. It does not guarantee that response construction and temporary memory allocation cannot harm process availability. That is a useful distinction when reviewing which commands an application user may invoke.

The commit's tests include very large offset and count values and permit the architecture-appropriate error behavior. Their purpose is to verify rejection or a bounded result at the arithmetic boundary. They do not require sending such inputs to a live shared database to understand the defect.

Random-member replies can multiply counts

The CVE-2023-22458 advisory identifies HRANDFIELD and ZRANDMEMBER. Crafted arguments could cause an assertion failure. It states that the issue affects Redis 6.2 or newer and names 6.2.9 and 7.0.8 as patched versions.

The 7.0.8 hash implementation bounds the count when WITHVALUES is present. Its accepted range is constrained to half of the signed long range in either direction. The sorted-set implementation applies the corresponding check when WITHSCORES is present.

Those options expand the information returned for each selected entry. The hash code's reply construction makes the multiplication visible, since the RESP2 form can use twice the selected-entry count for field-value output. A count can therefore be representable on its own while an expanded reply length is not.

The distinction generalizes to any interface that accepts an element count and later adds metadata per element. Validation has to consider the derived representation. Merely checking that an input converts to a signed integer leaves later multiplication outside that guarantee.

Authentication does not eliminate this availability risk

Both advisories describe authenticated callers. That qualification identifies who can reach the vulnerable operations, but it does not make an authorized application harmless to the shared server. Credentials establish access under a policy. The command implementation must still reject arguments that violate its internal resource assumptions.

The first advisory names patched versions 7.0.8, 6.2.9, and 6.0.17 for its affected branches. The random-member advisory has the narrower version history described above. These version sets should remain distinct because the commands and affected histories differ. A combined security release does not imply that every issue affects every historical branch.

The same release notes include a separate fix for blocking commands with subsecond timeouts that could otherwise block forever. That is another availability correction, but it has a different mechanism from the arithmetic flaws. Keeping it separate avoids attributing every failure addressed by the release to the two security advisories.

I regard the implementation changes as more informative than a generic instruction to distrust input. The string checker now owns the addition it validates. Sorting clamps range arguments to its vector, and expanded random-member replies bound their count before later arithmetic. Each correction ties input acceptance to the actual derived quantity that the server will use.