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; }