Skip to content

AmSdp::parse: contain parser exceptions instead of aborting on malformed SDP#555

Open
hecko wants to merge 1 commit into
masterfrom
hecko/amsdp-parse-catch-length-error
Open

AmSdp::parse: contain parser exceptions instead of aborting on malformed SDP#555
hecko wants to merge 1 commit into
masterfrom
hecko/amsdp-parse-catch-length-error

Conversation

@hecko

@hecko hecko commented Jul 11, 2026

Copy link
Copy Markdown
Contributor

Bug

parse_sdp_line_ex() and its helpers in core/AmSdp.cpp build std::string objects from raw pointer arithmetic with no lower-bound guard, for example:

c.address = string(connection_line, line_len - 7);              // IP4/IP6 c-line
c.address = string(connection_line, int(next - connection_line) - 2);
media     = string(media_line, int(next - media_line) - 1);

line_len is a size_t. On a truncated or malformed line (e.g. a c= line shorter than the assumed IN IPx prefix) line_len - 7 underflows to a huge value, and std::string throws std::length_error. The pointer-difference forms can likewise go negative and convert to a huge size_t.

AmSdp::parse() is called directly on attacker-supplied INVITE/UPDATE offer and answer bodies, and its callers do not catch. An unhandled throw propagates out of the SIP processing path and terminates the process — a remotely-triggerable DoS via a single crafted SDP body.

Fix

Wrap the parse_sdp_line_ex() call in try/catch and report a parse failure (return non-zero, matching the file's existing error-return convention) instead of letting the exception escape:

bool ret = true;
try {
  ret = parse_sdp_line_ex(this, s);
} catch(const std::exception& e) {
  ERROR("exception while parsing SDP: %s\n", e.what());
  return true;
} catch(...) {
  ERROR("unknown exception while parsing SDP\n");
  return true;
}

<stdexcept> is already included. No behavioural change for well-formed SDP.

Provenance

Backported from yeti-switch/sems, which guards the same parse_sdp_line_ex() call with try/catch for std::out_of_range and generic exceptions. Thanks to the yeti-switch maintainers for the fix.


Generated by Claude Code

parse_sdp_line_ex() and its helpers construct std::string objects from raw
pointer arithmetic, e.g. string(connection_line, line_len - 7) and
string(line, int(next - line) - 2), with no lower-bound check. On a
truncated or malformed SDP body those length expressions underflow to a
huge size_t and std::string throws std::length_error (or out_of_range).

AmSdp::parse() runs directly on attacker-supplied INVITE/UPDATE offer and
answer bodies, and its callers do not catch, so an unhandled throw
propagates out and terminates the process -- a remotely-triggerable DoS.

Wrap parse_sdp_line_ex() in try/catch and report a parse failure (return
non-zero, matching the existing error convention) instead of letting the
exception escape.

Backported from yeti-switch/sems, which guards the same parse_sdp_line_ex()
call with try/catch for std::out_of_range and generic exceptions.
Copilot AI review requested due to automatic review settings July 11, 2026 03:25

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens SDP parsing against malformed/truncated attacker-supplied SDP bodies by containing exceptions thrown during parsing, preventing an unhandled exception from terminating the SIP processing process (remotely-triggerable DoS).

Changes:

  • Wrap parse_sdp_line_ex() inside AmSdp::parse() in try/catch to prevent exceptions from escaping the SIP path.
  • Log parsing exceptions and return a non-zero parse error (consistent with AmSdp::parse()’s !=0 error contract).
  • Add in-code rationale documenting why exception containment is required for security/robustness.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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.

2 participants