summaryrefslogtreecommitdiff
path: root/epan/dissectors/packet-dtls.c
diff options
context:
space:
mode:
authorPeter Wu <peter@lekensteyn.nl>2015-07-17 16:31:32 +0200
committerPeter Wu <peter@lekensteyn.nl>2015-08-23 16:48:04 +0000
commit3ce60ed112cfaac7483c22d182a165bbd22cb7de (patch)
tree6ec362ca75e53c9cec50b6ecebb17c9bd5c7951e /epan/dissectors/packet-dtls.c
parent3703b4e3245479beeb19be8c6513fa3aebd7b2a0 (diff)
downloadwireshark-3ce60ed112cfaac7483c22d182a165bbd22cb7de.tar.gz
dtls: do not try to add a zero-length fragment
fragment_add does not like adding zero-length fragments, it causes a zero-length memcpy to NULL. According to RFC 6347, fragment_offset=0 and fragment_length=length is an unfragmented message, so fragment>0 and fragment_length=length=0 is a fragmented message. An empty fragment does not extend a previous message, so ignore it. Such fragments are produced by at least GnuTLS 3.3.7[1], so raise a warning instead of an error. Caught by ubsan: epan/tvbuff.c:783:10: runtime error: null pointer passed as argument 1, which is declared to never be null #0 0x7f5319f6ed64 in tvb_memcpy epan/tvbuff.c:783 ... #13 0x7f5319f27e2b in fragment_add epan/reassemble.c:1394 #14 0x7f531a5c70a4 in dissect_dtls_handshake epan/dissectors/packet-dtls.c:1257 [1]: http://comments.gmane.org/gmane.network.gnutls.general/3582 Change-Id: I70bf16d2fb64793d0deaabe612147e238b743b2e Ping-Bug: 11358 Reviewed-on: https://code.wireshark.org/review/9689 Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Peter Wu <peter@lekensteyn.nl>
Diffstat (limited to 'epan/dissectors/packet-dtls.c')
-rw-r--r--epan/dissectors/packet-dtls.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/epan/dissectors/packet-dtls.c b/epan/dissectors/packet-dtls.c
index 2748aa4a97..6060e42eef 100644
--- a/epan/dissectors/packet-dtls.c
+++ b/epan/dissectors/packet-dtls.c
@@ -129,6 +129,7 @@ static gint ett_dtls_fragment = -1;
static gint ett_dtls_fragments = -1;
static expert_field ei_dtls_handshake_fragment_length_too_long = EI_INIT;
+static expert_field ei_dtls_handshake_fragment_length_zero = EI_INIT;
static expert_field ei_dtls_handshake_fragment_past_end_msg = EI_INIT;
static expert_field ei_dtls_msg_len_diff_fragment = EI_INIT;
static expert_field ei_dtls_heartbeat_payload_length = EI_INIT;
@@ -1243,6 +1244,14 @@ dissect_dtls_handshake(tvbuff_t *tvb, packet_info *pinfo,
expert_add_info(pinfo, fragment_length_item, &ei_dtls_handshake_fragment_past_end_msg);
}
}
+ else if (fragment_offset > 0 && fragment_length == 0)
+ {
+ /* Fragmented message, but no actual fragment... Note that if a
+ * fragment was previously completed (reassembled_length == length),
+ * it is already dissected. */
+ expert_add_info(pinfo, fragment_length_item, &ei_dtls_handshake_fragment_length_zero);
+ continue;
+ }
else if (fragment_length < length)
{
fragmented = TRUE;
@@ -1874,6 +1883,7 @@ proto_register_dtls(void)
};
static ei_register_info ei[] = {
+ { &ei_dtls_handshake_fragment_length_zero, { "dtls.handshake.fragment_length.zero", PI_PROTOCOL, PI_WARN, "Zero-length fragment length for fragmented message", EXPFILL }},
{ &ei_dtls_handshake_fragment_length_too_long, { "dtls.handshake.fragment_length.too_long", PI_PROTOCOL, PI_ERROR, "Fragment length is larger than message length", EXPFILL }},
{ &ei_dtls_handshake_fragment_past_end_msg, { "dtls.handshake.fragment_past_end_msg", PI_PROTOCOL, PI_ERROR, "Fragment runs past the end of the message", EXPFILL }},
{ &ei_dtls_msg_len_diff_fragment, { "dtls.msg_len_diff_fragment", PI_PROTOCOL, PI_ERROR, "Message length differs from value in earlier fragment", EXPFILL }},