From b02a0ee48a51ccbb33ad76ce84ecb05409a6973a Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Thu, 1 Oct 2015 16:56:01 +0200 Subject: [PATCH] Fix crashes related to RTP Streams analysis 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 Petri-Dish: Peter Wu Tested-by: Petri Dish Buildbot Reviewed-by: Michael Mann --- ui/cli/tap-rtp.c | 2 +- ui/gtk/rtp_stream_dlg.c | 14 ++++++++++++-- ui/qt/rtp_stream_dialog.cpp | 10 ++++++++++ ui/qt/rtp_stream_dialog.h | 1 + ui/rtp_stream.h | 2 ++ ui/tap-rtp-common.c | 7 ++++++- 6 files changed, 32 insertions(+), 4 deletions(-) diff --git a/ui/cli/tap-rtp.c b/ui/cli/tap-rtp.c index eee1f13e9e..98190a0632 100644 --- a/ui/cli/tap-rtp.c +++ b/ui/cli/tap-rtp.c @@ -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_) diff --git a/ui/gtk/rtp_stream_dlg.c b/ui/gtk/rtp_stream_dlg.c index 8916eed598..d3dce19fb5 100644 --- a/ui/gtk/rtp_stream_dlg.c +++ b/ui/gtk/rtp_stream_dlg.c @@ -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) { diff --git a/ui/qt/rtp_stream_dialog.cpp b/ui/qt/rtp_stream_dialog.cpp index 52f96008b0..fa77c8e864 100644 --- a/ui/qt/rtp_stream_dialog.cpp +++ b/ui/qt/rtp_stream_dialog.cpp @@ -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 *)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 *)tapinfo->tap_data); diff --git a/ui/qt/rtp_stream_dialog.h b/ui/qt/rtp_stream_dialog.h index 8005a818ba..953d2e319c 100644 --- a/ui/qt/rtp_stream_dialog.h +++ b/ui/qt/rtp_stream_dialog.h @@ -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); diff --git a/ui/rtp_stream.h b/ui/rtp_stream.h index 358ec17890..d5c85b9f96 100644 --- a/ui/rtp_stream.h +++ b/ui/rtp_stream.h @@ -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 */ diff --git a/ui/tap-rtp-common.c b/ui/tap-rtp-common.c index f8d1e22280..f4a5b1aea3 100644 --- a/ui/tap-rtp-common.c +++ b/ui/tap-rtp-common.c @@ -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); } /*