From cc67f836c01b6f55f2ff70aa4df44a1b934d7404 Mon Sep 17 00:00:00 2001
From: John Thacker <johnthacker@gmail.com>
Date: Wed, 29 May 2024 14:23:04 +0000
Subject: [PATCH] SPRT: Fix crash

SDP can setup a RTP conversation with a setup frame before the current
frame, which changes the dissection on the second pass. If in the period
in the middle there is a SPRT packet, it can be dissected differently on
the second pass, and the SPRT conversation data won't be found on the
second pass.

Fix #19559 (at least prevent the crash. There's some more cleanup that
should happen.)


(cherry picked from commit 05f6364cbd766e8758f98c5ee2070aef27c1ffef)

Co-authored-by: John Thacker <johnthacker@gmail.com>
---
 epan/dissectors/packet-rtp.c  |  3 +++
 epan/dissectors/packet-sprt.c | 29 +++++++++++++++++------------
 2 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/epan/dissectors/packet-rtp.c b/epan/dissectors/packet-rtp.c
index 9731e03..6ec8f6f 100644
--- a/epan/dissectors/packet-rtp.c
+++ b/epan/dissectors/packet-rtp.c
@@ -1097,6 +1097,9 @@ srtp_add_address(packet_info *pinfo, const port_type ptype, address *addr, int p
      * If not, create a new conversation.
      */
     if (!p_conv || p_conv->setup_frame != setup_frame_number) {
+        /* XXX - If setup_frame_number < pinfo->num, creating this conversation
+         * can mean that the dissection is different on later passes.
+         */
         p_conv = conversation_new(setup_frame_number, addr, &null_addr, conversation_pt_to_endpoint_type(ptype),
                                   (guint32)port, (guint32)other_port,
                       NO_ADDR2 | (!other_port ? NO_PORT2 : 0));
diff --git a/epan/dissectors/packet-sprt.c b/epan/dissectors/packet-sprt.c
index 87e543c..568d242 100644
--- a/epan/dissectors/packet-sprt.c
+++ b/epan/dissectors/packet-sprt.c
@@ -1341,6 +1341,23 @@ dissect_sprt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
     /*guint16 tcn;*/
     /*guint16 sqn;*/
 
+    /* Get conversation data, or create it if not found */
+    p_conv_data = find_sprt_conversation_data(pinfo);
+    if (!p_conv_data)
+    {
+        sprt_add_address(pinfo,
+            &pinfo->src, pinfo->srcport,
+            0,
+            "SPRT stream",
+            pinfo->num);
+        p_conv_data = find_sprt_conversation_data(pinfo);
+        if (!p_conv_data) {
+            // This shouldn't happen; likely a new RTP conversation was set up
+            // after this frame but with a setup frame before this one.
+            return 0;
+        }
+    }
+
     /* Make entries in Protocol column and Info column on summary display */
     col_set_str(pinfo->cinfo, COL_PROTOCOL, "SPRT");
     col_clear(pinfo->cinfo, COL_INFO);
@@ -1395,18 +1412,6 @@ dissect_sprt(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_
 
     noa = (tvb_get_ntohs(tvb, offset + 4) & 0xC000) >> 14;
 
-    /* Get conversation data, or create it if not found */
-    p_conv_data = find_sprt_conversation_data(pinfo);
-    if (!p_conv_data)
-    {
-        sprt_add_address(pinfo,
-            &pinfo->src, pinfo->srcport,
-            0,
-            "SPRT stream",
-            pinfo->num);
-        p_conv_data = find_sprt_conversation_data(pinfo);
-    }
-
     proto_tree_add_item(sprt_tree, hf_sprt_header_extension_bit, tvb, offset, 1, ENC_BIG_ENDIAN);
     proto_tree_add_item(sprt_tree, hf_sprt_subsession_id, tvb, offset, 1, ENC_BIG_ENDIAN);
     offset++;
-- 
2.46.2

