On 15.01.2014 18:06, Yuto KAWAMURA(kawamuray) wrote:
From: "Yuto KAWAMURA(kawamuray)"
<kawamuray.dadada(a)gmail.com>
Introduce Wireshark dissector plugin which adds support to Wireshark
for dissecting libvirt RPC protocol.
Added following files to build Wireshark dissector from libvirt source
tree.
* tools/wireshark/*: Source tree of Wireshark dissector plugin.
Added followings to configure.ac or Makefile.am.
configure.ac
* --with-wireshark-dissector: Enable support for building Wireshark
dissector.
* --with-ws-plugindir: Specify wireshark plugin directory that dissector
will installed.
* Added tools/wireshark/{Makefile,src/Makefile} to AC_CONFIG_FILES.
Makefile.am
* Added tools/wireshark/ to SUBDIR.
---
.gitignore | 2 +
Makefile.am | 3 +-
cfg.mk | 8 +-
configure.ac | 72 ++-
tools/wireshark/Makefile.am | 22 +
tools/wireshark/README.md | 31 +
tools/wireshark/src/Makefile.am | 42 ++
tools/wireshark/src/packet-libvirt.c | 512 ++++++++++++++++
tools/wireshark/src/packet-libvirt.h | 128 ++++
tools/wireshark/util/genxdrstub.pl | 1011 +++++++++++++++++++++++++++++++
tools/wireshark/util/make-dissector-reg | 198 ++++++
11 files changed, 2023 insertions(+), 6 deletions(-)
create mode 100644 tools/wireshark/Makefile.am
create mode 100644 tools/wireshark/README.md
create mode 100644 tools/wireshark/src/Makefile.am
create mode 100644 tools/wireshark/src/packet-libvirt.c
create mode 100644 tools/wireshark/src/packet-libvirt.h
create mode 100755 tools/wireshark/util/genxdrstub.pl
create mode 100755 tools/wireshark/util/make-dissector-reg
diff --git a/tools/wireshark/src/packet-libvirt.c
b/tools/wireshark/src/packet-libvirt.c
new file mode 100644
index 0000000..2d0350c
--- /dev/null
+++ b/tools/wireshark/src/packet-libvirt.c
+static void
+dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ goffset offset;
+ guint32 prog, proc, type, serial, status;
+ const value_string *vs;
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "Libvirt");
+ col_clear(pinfo->cinfo, COL_INFO);
+
+ offset = 4; /* End of length field */
+ prog = tvb_get_ntohl(tvb, offset); offset += 4;
+ offset += 4; /* Ignore version header field */
+ proc = tvb_get_ntohl(tvb, offset); offset += 4;
+ type = tvb_get_ntohl(tvb, offset); offset += 4;
+ serial = tvb_get_ntohl(tvb, offset); offset += 4;
+ status = tvb_get_ntohl(tvb, offset); offset += 4;
+
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Prog=%s",
+ val_to_str(prog, program_strings, "%x"));
+
+ vs = get_program_data(prog, VIR_PROGRAM_PROCSTRINGS);
+ if (vs == NULL) {
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%u", proc);
+ } else {
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Proc=%s",
val_to_str(proc, vs, "%d"));
+ }
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, " Type=%s Serial=%u
Status=%s",
+ val_to_str(type, type_strings, "%d"), serial,
+ val_to_str(status, status_strings, "%d"));
+
+ if (tree) {
+ gint hf_proc;
+ proto_item *ti;
+ proto_tree *libvirt_tree;
+
+ ti = proto_tree_add_item(tree, proto_libvirt, tvb, 0, tvb_length(tvb), ENC_NA);
+ libvirt_tree = proto_item_add_subtree(ti, ett_libvirt);
+
+ offset = 0;
+ proto_tree_add_item(libvirt_tree, hf_libvirt_length, tvb, offset, 4, ENC_NA);
offset += 4;
+ proto_tree_add_item(libvirt_tree, hf_libvirt_program, tvb, offset, 4, ENC_NA);
offset += 4;
+ proto_tree_add_item(libvirt_tree, hf_libvirt_version, tvb, offset, 4, ENC_NA);
offset += 4;
+
+ hf_proc = *(int *)get_program_data(prog, VIR_PROGRAM_PROCHFVAR);
There's a possible NULL dereference here. get_program might return NULL in case @prog
is not one of REMOTE, QEMU, LXC, KEEPALIVE. This can possibly happen and it did for me
indeed:
Program terminated with signal 11, Segmentation fault.
#0 0x00007fac1cc60a86 in dissect_libvirt_message (tvb=0x387acc0, pinfo=0x7fffb9a03100,
tree=0x3883090) at packet-libvirt.c:396
396 hf_proc = *(int *)get_program_data(prog, VIR_PROGRAM_PROCHFVAR);
(gdb) bt
#0 0x00007fac1cc60a86 in dissect_libvirt_message (tvb=0x387acc0, pinfo=0x7fffb9a03100,
tree=0x3883090) at packet-libvirt.c:396
#1 0x00000034469198fe in tcp_dissect_pdus () from /usr/lib64/libwireshark.so.3
#2 0x00007fac1cc60c0c in dissect_libvirt (tvb=0x3879aa0, pinfo=0x7fffb9a03100,
tree=0x3883090) at packet-libvirt.c:424
#3 0x00000034462dff54 in ?? () from /usr/lib64/libwireshark.so.3
#4 0x00000034462e0608 in ?? () from /usr/lib64/libwireshark.so.3
#5 0x00000034462e0e0c in ?? () from /usr/lib64/libwireshark.so.3
#6 0x00000034462e0e67 in dissector_try_uint () from /usr/lib64/libwireshark.so.3
...
(gdb) p /x VIR_PROGRAM_PROCHFVAR
$1 = 0x0
(gdb) p /x prog
$2 = 0xd21c44f9
This happened if I used sasl for authentication (auth_tcp="sasl" listen_tcp=1
listen_tls=0)
+ if (hf_proc == -1) {
+ proto_tree_add_none_format(libvirt_tree, -1, tvb, offset, 4, "Unknown
proc: %u", proc);
+ } else {
+ proto_tree_add_item(libvirt_tree, hf_proc, tvb, offset, 4, ENC_NA);
+ }
+ offset += 4;
I've tried to fixed this by applying:
@@ -381,7 +381,7 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree
*tree)
val_to_str(status, status_strings, "%d"));
if (tree) {
- gint hf_proc;
+ gint *hf_proc;
proto_item *ti;
proto_tree *libvirt_tree;
@@ -393,11 +393,11 @@ dissect_libvirt_message(tvbuff_t *tvb, packet_info *pinfo,
proto_tree *tree)
proto_tree_add_item(libvirt_tree, hf_libvirt_program, tvb, offset, 4, ENC_NA);
offset += 4;
proto_tree_add_item(libvirt_tree, hf_libvirt_version, tvb, offset, 4, ENC_NA);
offset += 4;
- hf_proc = *(int *)get_program_data(prog, VIR_PROGRAM_PROCHFVAR);
- if (hf_proc == -1) {
+ hf_proc = (int *)get_program_data(prog, VIR_PROGRAM_PROCHFVAR);
+ if (!hf_proc || *hf_proc == -1) {
proto_tree_add_none_format(libvirt_tree, -1, tvb, offset, 4, "Unknown
proc: %u", proc);
} else {
- proto_tree_add_item(libvirt_tree, hf_proc, tvb, offset, 4, ENC_NA);
+ proto_tree_add_item(libvirt_tree, *hf_proc, tvb, offset, 4, ENC_NA);
}
offset += 4;
but it worked only partially as then I was seeing this error messages (but no segfault :)
):
12:29:09 Warn Dissector bug, protocol libvirt, in packet 32: proto.c:1854: failed
assertion "(guint)hfindex < gpa_hfinfo.len" (Unregistered hf!)
The error message kept repeating over and over again. The rest of the patch looks okay.
Once you fix this (sending a follow-up patch is just fine) I'll push this. Thanks for
taking care of the dissector!
Michal