Skip to content

cachedb_redis: fix safety issues in cluster redirect parsing#3854

Open
NormB wants to merge 1 commit intoOpenSIPS:masterfrom
NormB:mr/fix-redis-cluster-safety
Open

cachedb_redis: fix safety issues in cluster redirect parsing#3854
NormB wants to merge 1 commit intoOpenSIPS:masterfrom
NormB:mr/fix-redis-cluster-safety

Conversation

@NormB
Copy link
Copy Markdown
Member

@NormB NormB commented Mar 30, 2026

Summary

Fix several correctness and safety issues in parse_moved_reply() and the MOVED redirect handler.

Details

Integer overflow in slot parsing — the digit accumulation loop slot = slot * 10 + (*p - '0') has no upper bound check. A malformed MOVED reply with a long digit string causes signed integer overflow (undefined behavior in C). Fixed by returning ERR_INVALID_SLOT when slot > 16383 during parsing.

Integer overflow in port parsing — same issue in the port digit loop. The existing post-loop check port > 65535 is insufficient because signed overflow is UB before the check executes. Fixed by returning ERR_INVALID_PORT when port > 65535 during digit accumulation.

Undefined behavior in no-colon fallback — when the endpoint has no colon (no explicit port), the code compares out->endpoint.s < end where out->endpoint.s was set to NULL two lines above. Comparing a null pointer to a non-null pointer is undefined behavior per the C standard. Fixed by using p < end instead, which holds the correct scan position.

Unnecessary heap allocation — the redis_moved struct in the MOVED handler is heap-allocated via pkg_malloc and freed within the same scope. Since the struct is ~24 bytes and never outlives the enclosing block, this is replaced with stack allocation, eliminating the pkg_malloc/pkg_free calls and the OOM error path.

Compatibility

No behavioral change for correctly-formed Redis replies. The overflow checks add early rejection of malformed input that would previously have caused undefined behavior.

Closing issues

Partially addresses #2811

Fix several correctness and safety issues in parse_moved_reply()
and the MOVED redirect handler:

- Add slot value overflow protection: return ERR_INVALID_SLOT
  when parsed slot exceeds 16383 during digit accumulation,
  preventing signed integer overflow on malformed MOVED replies.

- Add port value overflow protection: return ERR_INVALID_PORT
  when parsed port exceeds 65535 during digit accumulation,
  complementing the existing post-loop range check and preventing
  signed integer overflow on malformed input.

- Fix undefined behavior in the no-colon endpoint fallback path:
  replace comparison of potentially-NULL out->endpoint.s against
  end pointer with (p < end), which achieves the same logic using
  the scan position variable that is always valid.

- Replace pkg_malloc heap allocation of redis_moved struct with
  stack allocation in the MOVED handler. The struct is small
  (~24 bytes) and never outlives the enclosing scope, making heap
  allocation unnecessary. This eliminates the OOM error path and
  two pkg_free() calls.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant