Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] Memory Leak when receiving malformed SDP lines #3589

Open
nikbyte opened this issue Feb 21, 2025 · 0 comments
Open

[BUG] Memory Leak when receiving malformed SDP lines #3589

nikbyte opened this issue Feb 21, 2025 · 0 comments

Comments

@nikbyte
Copy link
Member

nikbyte commented Feb 21, 2025

Description

When OpenSIPS receives an INVITE with SDP lines incorrectly separated by \n only (instead of the standard \r\n) and then uses sdp.line transformation, it can end up concatenating two lines. For example:

c=IN IP4 8.8.8.8
t=0 0

In a well-formed SDP, c= and t= lines would be separated by \r\n. However, here they're effectively joined into one token that OpenSIPS sees as:

c=IN IP4 8.8.8.8
t=0 0

From the configuration side, a snippet like:

$avp(sdp_ip) := $(rb{sdp.line,c,0}); 
avp_subst("$avp(sdp_ip)", "/^c=IN IP[46] (.*)$$/\1/");

will produce a concatenated line rather than just the c= line. Subsequently, if we insert that resulting string into a SIP header, e.g.,

append_hf("X-SDPIP: $avp(sdp_ip):$avp(sdp_port)\r\n");

we end up with a new message like:

X-HCV-OrigSDP: 8.8.8.8
t=0 0:21022

in the outgoing INVITE. Now OpenSIPS itself, upon receiving (or re-processing) this generated INVITE, sees t=0 0 as a short header name t: (similar to To:) and tries to parse it. This leads to a parsing error and triggers a memory leak where the parser-allocated memory for this invalid header does not get correctly freed.

Steps to Reproduce

  1. Send an INVITE to OpenSIPS with a c-line ending by \n instead of \r\n.

  2. Let OpenSIPS parse that SDP and store it in an AVP.

  3. Use sdp.line transformation to manipulate the combined line, then inject it back into an outgoing header (e.g., via append_hf()).

  4. OpenSIPS regenerates an INVITE containing lines like:

    X-HCV-OrigSDP: 8.8.8.8
    t=0 0:21022
    
  5. Now OpenSIPS re-parses its own generated INVITE. The partial line t=0 0:21022 is detected as an invalid short To: header, and that parse path causes a memory leak.

Analysis of the Problem

  • The root cause is a malformed SDP line that merges c= and t= with only a \n.
  • OpenSIPS fails to split them as separate lines in the script, and they get written back into a new INVITE.
  • During the subsequent parse attempt, the line t=0 0:21022 is misread as a SIP header. The parser attempts to allocate memory to parse it, fails, and does not free what it allocated (i.e., a parse-time memory leak).
  • This behavior eventually can degrade OpenSIPS, especially under high call rates or repeated occurrences of malformed lines.

Proposed Fix / Patch

A patch has been developed that ensures memory allocated for malformed or partially parsed headers is always freed, preventing leaks even if the line is invalid. The patch does not change how OpenSIPS treats non-standard SDP lines logically; it only addresses the memory leak that occurs during the parse error.

diff --git a/parser/msg_parser.c b/parser/msg_parser.c
index ad84ac611..b02473e28 100644
--- a/parser/msg_parser.c
+++ b/parser/msg_parser.c
@@ -840,6 +840,9 @@ int parse_msg(char* buf, unsigned int len, struct sip_msg* msg)
   return 0;

 error:
+  // Free the SIP message if it has already been created to prevent memory leaks.
+  free_sip_msg(msg);
+
   /* more debugging, msg->orig is/should be null terminated*/
   LM_ERR("message=<%.*s>\n", (int)len, ZSW(buf));
   return -1;

Additional Notes

  • While RFCs dictate that \r\n must be used to separate lines, some upstream systems may produce only \n. This is not RFC-compliant, but real-world scenarios often violate specs.
  • The snippet using sdp.line transformation is correct for normal well-formed inputs but leads to unpredictable results with malformed lines.

Next Steps

  • Merge the patch that fixes the memory leak in the parse procedure, ensuring that any allocated parse buffers are correctly freed.
  • Optionally, consider implementing an additional check in sdp_parse() to detect and reject such SDPs, preventing malformed SIP requests/replies from being processed.
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

No branches or pull requests

1 participant