From 32df432f915a48cdd6df15cdc8ba0c068550825b Mon Sep 17 00:00:00 2001 From: hecko <855807+hecko@users.noreply.github.com> Date: Fri, 10 Jul 2026 03:29:23 +0000 Subject: [PATCH] parse_cseq: reject overlarge CSeq numbers to avoid unsigned overflow parse_cseq accumulates the numeric CSeq field digit-by-digit into the unsigned int sip_cseq::num with no bound check. A CSeq header with a number wider than 32 bits (e.g. 'CSeq: 99999999999999 INVITE') silently wraps, so distinct on-wire CSeq strings can collapse to the same value. That number feeds transaction matching, so the wrap can corrupt matching and mis-route in/out requests. Every other scalar SIP field parser in the codebase already rejects overlarge values. Reject the header once the accumulator would exceed UINT_MAX. Backport of the intent of yeti-switch/sems f9d7c3f2. --- core/sip/parse_cseq.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/core/sip/parse_cseq.cpp b/core/sip/parse_cseq.cpp index 92f15d1b6..da67be976 100644 --- a/core/sip/parse_cseq.cpp +++ b/core/sip/parse_cseq.cpp @@ -32,6 +32,8 @@ #include "log.h" +#include + int parse_cseq(sip_cseq* cseq, const char* beg, int len) { enum { @@ -65,6 +67,14 @@ int parse_cseq(sip_cseq* cseq, const char* beg, int len) if(!IS_DIGIT(*c)){ return MALFORMED_SIP_MSG; } + // reject overlarge CSeq numbers: the RFC 3261 CSeq value is a + // 32-bit quantity and 'num' is unsigned int; without this guard + // the accumulation silently wraps, so distinct on-wire CSeq + // strings can collapse to the same value and corrupt + // transaction matching. + if(cseq->num > (UINT_MAX - (unsigned int)(*c - '0')) / 10){ + return MALFORMED_SIP_MSG; + } cseq->num = cseq->num*10 + *c - '0'; break; }