From 99f9bec089c3d25f1a6e3b4981e4cf24b2dfc024 Mon Sep 17 00:00:00 2001 From: hecko <855807+hecko@users.noreply.github.com> Date: Sat, 11 Jul 2026 03:25:04 +0000 Subject: [PATCH] AmSdp::parse: contain parser exceptions instead of aborting 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. --- core/AmSdp.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/core/AmSdp.cpp b/core/AmSdp.cpp index d802a0268..9ce8fccc9 100644 --- a/core/AmSdp.cpp +++ b/core/AmSdp.cpp @@ -304,8 +304,24 @@ int AmSdp::parse(const char* _sdp_msg) char* s = (char*)_sdp_msg; clear(); - bool ret = parse_sdp_line_ex(this,s); - + // parse_sdp_line_ex() and its helpers build std::string objects from raw + // pointer arithmetic (e.g. string(line, len-7)) with no lower-bound guard. + // A truncated/malformed SDP body can make that length underflow to a huge + // size_t and throw std::length_error (or out_of_range). parse() is called + // directly on attacker-supplied offer/answer bodies and callers do not + // catch, so an unhandled throw aborts the process -- a remote DoS. Contain + // any such exception here and report a parse failure instead. + 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; + } + if(!ret && conn.address.empty()){ for(vector::iterator it = media.begin(); !ret && (it != media.end()); ++it)