Fix crashes related to RTP Streams analysis
authorPeter Wu <peter@lekensteyn.nl>
Thu, 1 Oct 2015 14:56:01 +0000 (16:56 +0200)
committerMichael Mann <mmann78@netscape.net>
Thu, 1 Oct 2015 20:46:50 +0000 (20:46 +0000)
The data that describes RTP streams become invalid when packets are
re-dissected. This results in a crash in GTK when the "RTP Analyse"
option is used and and a crash in Qt when the display filter is changed
while the RTP Streams dialog is open.

Fix this by adding a tap_reset callback (modelled after mcaststream) to
the RTP tap listener that allows the GTK+ and Qt dialogs to clear the
displayed list of RTP streams.

Bug: 10016
Change-Id: I7478678db63d7ac8110c44c163844e9f66fad9e9
Reviewed-on: https://code.wireshark.org/review/10728
Reviewed-by: Peter Wu <peter@lekensteyn.nl>
Petri-Dish: Peter Wu <peter@lekensteyn.nl>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
ui/cli/tap-rtp.c
ui/gtk/rtp_stream_dlg.c
ui/qt/rtp_stream_dialog.cpp
ui/qt/rtp_stream_dialog.h
ui/rtp_stream.h
ui/tap-rtp-common.c

index eee1f13e9eba61d5eac2aeb901f43f7c98391c08..98190a0632e06040d2cede1183973e66421527a9 100644 (file)
@@ -51,7 +51,7 @@ void register_tap_listener_rtp_streams(void);
 /* The one and only global rtpstream_tapinfo_t structure for tshark and wireshark.
  */
 static rtpstream_tapinfo_t the_tapinfo_struct =
-        {NULL, NULL, NULL, 0, NULL, 0, TAP_ANALYSE, NULL, NULL, NULL, FALSE};
+        {NULL, NULL, NULL, NULL, 0, NULL, 0, TAP_ANALYSE, NULL, NULL, NULL, FALSE};
 
 static void
 rtp_streams_stat_draw(void *arg _U_)
index 8916eed5980886684670dfe4fa32951dbb7162ed..d3dce19fb577f43acdbdcee4128f6ad95b081fd5 100644 (file)
@@ -51,6 +51,7 @@ static const gchar FWD_LABEL_TEXT[] = "Select a forward stream with left mouse b
 static const gchar FWD_ONLY_LABEL_TEXT[] = "Select a forward stream with Ctrl + left mouse button";
 static const gchar REV_LABEL_TEXT[] = "Select a reverse stream with Ctrl + left mouse button";
 
+static void rtpstream_tap_reset(rtpstream_tapinfo_t *ti_ptr);
 static void rtpstream_tap_draw(rtpstream_tapinfo_t *ti_ptr);
 static void rtpstream_dlg_mark_packet(rtpstream_tapinfo_t *tapinfo, frame_data *fd);
 void register_tap_listener_rtp_stream_dlg(void);
@@ -58,8 +59,8 @@ void register_tap_listener_rtp_stream_dlg(void);
 /* The one and only global rtpstream_tapinfo_t structure for tshark and wireshark.
  */
 static rtpstream_tapinfo_t the_tapinfo_struct =
-    { rtpstream_tap_draw, rtpstream_dlg_mark_packet, NULL, 0, NULL, 0,
-      TAP_ANALYSE, NULL, NULL, NULL, FALSE
+    { rtpstream_tap_reset, rtpstream_tap_draw, rtpstream_dlg_mark_packet,
+      NULL, 0, NULL, 0, TAP_ANALYSE, NULL, NULL, NULL, FALSE
     };
 
 /****************************************************************************/
@@ -1104,6 +1105,15 @@ rtpstream_dlg_update(GList *list_lcl)
     last_list = list_lcl;
 }
 
+static void
+rtpstream_tap_reset(rtpstream_tapinfo_t *tapinfo _U_)
+{
+    if (rtp_stream_dlg != NULL) {
+        gtk_list_store_clear(list_store);
+        streams_nb = 0;
+    }
+}
+
 static void
 rtpstream_tap_draw(rtpstream_tapinfo_t *tapinfo)
 {
index 52f96008b0ff3fec2c626b05188521a101790c27..fa77c8e8641aca7ee43358c7e4d1969135654130 100644 (file)
@@ -265,6 +265,7 @@ RtpStreamDialog::RtpStreamDialog(QWidget &parent, CaptureFile &cf) :
 
     /* Register the tap listener */
     memset(&tapinfo_, 0, sizeof(rtpstream_tapinfo_t));
+    tapinfo_.tap_reset = tapReset;
     tapinfo_.tap_draw = tapDraw;
     tapinfo_.tap_mark_packet = tapMarkPacket;
     tapinfo_.tap_data = this;
@@ -314,6 +315,15 @@ bool RtpStreamDialog::eventFilter(QObject *, QEvent *event)
     return false;
 }
 
+void RtpStreamDialog::tapReset(rtpstream_tapinfo_t *tapinfo)
+{
+    RtpStreamDialog *rtp_stream_dialog = dynamic_cast<RtpStreamDialog *>((RtpStreamDialog *)tapinfo->tap_data);
+    if (rtp_stream_dialog) {
+        /* invalidate items which refer to old strinfo_list items. */
+        rtp_stream_dialog->ui->streamTreeWidget->clear();
+    }
+}
+
 void RtpStreamDialog::tapDraw(rtpstream_tapinfo_t *tapinfo)
 {
     RtpStreamDialog *rtp_stream_dialog = dynamic_cast<RtpStreamDialog *>((RtpStreamDialog *)tapinfo->tap_data);
index 8005a818ba6ebb435ad72572f7de5aa2c180cf39..953d2e319c0ecd22c2d4becb9b8383e5fce9b362 100644 (file)
@@ -63,6 +63,7 @@ private:
     QMenu ctx_menu_;
     bool need_redraw_;
 
+    static void tapReset(rtpstream_tapinfo_t *tapinfo);
     static void tapDraw(rtpstream_tapinfo_t *tapinfo);
     static void tapMarkPacket(rtpstream_tapinfo_t *tapinfo, frame_data *fd);
 
index 358ec1789071340aae142cf68c96af1aa2d1dfdd..d5c85b9f96ea2b7e94b24d78d7a53edad08a4e3f 100644 (file)
@@ -89,12 +89,14 @@ typedef enum
 
 typedef struct _rtpstream_tapinfo rtpstream_tapinfo_t;
 
+typedef void (*rtpstream_tap_reset_cb)(rtpstream_tapinfo_t *tapinfo);
 typedef void (*rtpstream_tap_draw_cb)(rtpstream_tapinfo_t *tapinfo);
 typedef void (*tap_mark_packet_cb)(rtpstream_tapinfo_t *tapinfo, frame_data *fd);
 
 /* structure that holds the information about all detected streams */
 /** struct holding all information of the tap */
 struct _rtpstream_tapinfo {
+    rtpstream_tap_reset_cb tap_reset;       /**< tap reset callback */
     rtpstream_tap_draw_cb tap_draw;         /**< tap draw callback */
     tap_mark_packet_cb tap_mark_packet;     /**< packet marking callback */
     void *tap_data;                         /**< data for tap callbacks */
index f8d1e22280069046294d64ba0d7edcbc1898da2e..f4a5b1aea39421a7e20fcbba505a55431772e959 100644 (file)
@@ -101,7 +101,12 @@ void rtpstream_reset(rtpstream_tapinfo_t *tapinfo)
 
 void rtpstream_reset_cb(void *arg)
 {
-       rtpstream_reset((rtpstream_tapinfo_t *)arg);
+       rtpstream_tapinfo_t *ti =(rtpstream_tapinfo_t *)arg;
+       if (ti->tap_reset) {
+               /* Give listeners a chance to cleanup references. */
+               ti->tap_reset(ti);
+       }
+       rtpstream_reset(ti);
 }
 
 /*