parse_cseq: reject overlarge CSeq numbers to avoid unsigned overflow#553
Open
hecko wants to merge 1 commit into
Open
parse_cseq: reject overlarge CSeq numbers to avoid unsigned overflow#553hecko wants to merge 1 commit into
hecko wants to merge 1 commit into
Conversation
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.
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot couldn't run its full agentic review because no GitHub Actions runner was available. Make sure your repository has a runner available to run Copilot's review, or add a copilot-setup-steps.yml file specifying one with the runs-on attribute. See the docs for more details.
This PR addresses a parsing bug in parse_cseq where overly large numeric CSeq values could overflow an unsigned int accumulator and silently wrap, potentially corrupting SIP transaction matching.
Changes:
- Add an overflow guard while accumulating
sip_cseq::numdigit-by-digit. - Include a header to access
UINT_MAXfor the overflow calculation.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| #include "log.h" | ||
|
|
||
| #include <limits.h> |
Comment on lines
+70
to
78
| // 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'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug
parse_cseq(core/sip/parse_cseq.cpp) accumulates the numeric CSeq field digit-by-digit intosip_cseq::num(anunsigned int) with no bound check:A CSeq header whose number is wider than 32 bits (e.g.
CSeq: 99999999999999 INVITE) silently wraps the accumulator, so two distinct on-wire CSeq strings can collapse to the same 32-bit value.numfeeds transaction matching (core/sip/trans_table.cpp) and is propagated to the application layer, so the wrap can corrupt transaction matching / request routing. It is triggerable by a single crafted request or reply — no dialog or auth required. Every other scalar SIP field parser in the tree (Content-Length, theparse_100relREAD_NUMBERpath) already rejects overlarge values;parse_cseqwas the gap.Fix
Reject the header as malformed once the next digit would overflow
UINT_MAX:Validation
sip_cseq::numisunsigned int(parse_cseq.h) and that the accumulation has no existing guard in currentmaster.Acknowledgement
Backport of the intent of the yeti-switch/sems fix, commit
f9d7c3f2c789c74dddfc3231b4cec8420b2bbfcd("fix Scalar Fields with Overlarge Values checking"). The bound check is expressed with the primitives available in this tree rather than yeti's helper macros. Thanks to the yeti-switch maintainers.Generated by Claude Code