diff options
author | Martin Kaiser <wireshark@kaiser.cx> | 2020-04-13 11:40:17 +0200 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2020-04-15 14:27:39 +0000 |
commit | 759fb119a723e660c712cc7f319b1e1b31a5765c (patch) | |
tree | 602eb7d4a3eb1a47a16aa8b4e976b1d3403c20ae /ui | |
parent | 040c31c269e953412ec044d861ed3dee5269dbec (diff) |
FrameInformation: fix a crash in the destructor
It's possible to create a FrameInformation object that's not backed by
any frame data. In this case, fi_ is NULL and loadFrameTree() does not
run a dissection. However, we run epan_dissect_cleanup() unconditionally
in the destructor, even if edt_ is uninitialized. This causes a crash
when wireshark is closed.
Convert edt_ into a pointer. Run the cleanup only if we ran the
dissection before.
The issue can be reproduced by applying a display filter that makes the
list of the packets smaller than the packet list window. Right click
onto an "empty" part of the packet list and select "Mark/Unmark Frame".
Exiting wireshark at this point causes a segmentation fault
Thread 1 "wireshark" received signal SIGSEGV, Segmentation fault.
tvb_free_chain (tvb=0xf000e000d000c) at ../epan/tvbuff.c:124
124 tvb_free_internal(tvb);
(gdb) bt
#0 tvb_free_chain (tvb=0xf000e000d000c) at ../epan/tvbuff.c:124
#1 0x00007ffff430491e in epan_dissect_cleanup (edt=0x555558075b48) at ../epan/epan.c:648
#2 0x00005555558fa5a6 in FrameInformation::~FrameInformation (this=0x555558075b20,
__in_chrg=<optimized out>) at ../ui/qt/utils/frame_information.cpp:57
#3 0x00005555558fa5e9 in FrameInformation::~FrameInformation (this=0x555558075b20,
__in_chrg=<optimized out>) at ../ui/qt/utils/frame_information.cpp:55
...
#12 0x00005555559a74f7 in PacketList::~PacketList (this=0x55555602e930,
__in_chrg=<optimized out>) at /usr/include/x86_64-linux-gnu/qt5/QtCore/qstring.h:1130
Change-Id: I347dd4901b4e08c37008ff25ac1f20a67555d9fd
Reviewed-on: https://code.wireshark.org/review/36825
Reviewed-by: Martin Kaiser <wireshark@kaiser.cx>
Petri-Dish: Martin Kaiser <wireshark@kaiser.cx>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'ui')
-rw-r--r-- | ui/qt/utils/frame_information.cpp | 26 | ||||
-rw-r--r-- | ui/qt/utils/frame_information.h | 2 |
2 files changed, 17 insertions, 11 deletions
diff --git a/ui/qt/utils/frame_information.cpp b/ui/qt/utils/frame_information.cpp index 3599d41aed..d56be04a1d 100644 --- a/ui/qt/utils/frame_information.cpp +++ b/ui/qt/utils/frame_information.cpp @@ -27,7 +27,8 @@ FrameInformation::FrameInformation(CaptureFile * capfile, frame_data * fi, QObject * parent) :QObject(parent), fi_(fi), - cap_file_(capfile) + cap_file_(capfile), + edt_(Q_NULLPTR) { wtap_rec_init(&rec_); ws_buffer_init(&buf_, 1514); @@ -42,19 +43,24 @@ void FrameInformation::loadFrameTree() if (!cf_read_record(cap_file_->capFile(), fi_, &rec_, &buf_)) return; + edt_ = g_new0(epan_dissect_t, 1); + /* proto tree, visible. We need a proto tree if there's custom columns */ - epan_dissect_init(&edt_, cap_file_->capFile()->epan, TRUE, TRUE); - col_custom_prime_edt(&edt_, &(cap_file_->capFile()->cinfo)); + epan_dissect_init(edt_, cap_file_->capFile()->epan, TRUE, TRUE); + col_custom_prime_edt(edt_, &(cap_file_->capFile()->cinfo)); - epan_dissect_run(&edt_, cap_file_->capFile()->cd_t, &rec_, + epan_dissect_run(edt_, cap_file_->capFile()->cd_t, &rec_, frame_tvbuff_new_buffer(&cap_file_->capFile()->provider, fi_, &buf_), fi_, &(cap_file_->capFile()->cinfo)); - epan_dissect_fill_in_columns(&edt_, TRUE, TRUE); + epan_dissect_fill_in_columns(edt_, TRUE, TRUE); } FrameInformation::~FrameInformation() { - epan_dissect_cleanup(&edt_); + if (edt_) { + epan_dissect_cleanup(edt_); + g_free(edt_); + } wtap_rec_cleanup(&rec_); ws_buffer_free(&buf_); } @@ -63,7 +69,7 @@ bool FrameInformation::isValid() { bool ret = false; - if (fi_ && cap_file_ && edt_.tvb) + if (fi_ && cap_file_ && edt_ && edt_->tvb) { ret = true; } @@ -85,12 +91,12 @@ int FrameInformation::frameNum() const const QByteArray FrameInformation::printableData() { - if (! fi_) + if (!fi_ || !edt_) return QByteArray(); - int length = tvb_captured_length(edt_.tvb); - const char *data = (const char *)tvb_get_ptr(edt_.tvb, 0, length); + int length = tvb_captured_length(edt_->tvb); + const char *data = (const char *)tvb_get_ptr(edt_->tvb, 0, length); return QByteArray(data, length); } /* diff --git a/ui/qt/utils/frame_information.h b/ui/qt/utils/frame_information.h index a362e5de71..012683ae36 100644 --- a/ui/qt/utils/frame_information.h +++ b/ui/qt/utils/frame_information.h @@ -45,7 +45,7 @@ private: frame_data * fi_; CaptureFile * cap_file_; - epan_dissect_t edt_; + epan_dissect_t * edt_; wtap_rec rec_; /* Record metadata */ Buffer buf_; /* Record data */ |