diff options
author | Peter Wu <peter@lekensteyn.nl> | 2015-07-17 16:31:32 +0200 |
---|---|---|
committer | Peter Wu <peter@lekensteyn.nl> | 2015-08-23 16:48:04 +0000 |
commit | 3ce60ed112cfaac7483c22d182a165bbd22cb7de (patch) | |
tree | 6ec362ca75e53c9cec50b6ecebb17c9bd5c7951e /epan/dissectors/packet-dtls.c | |
parent | 3703b4e3245479beeb19be8c6513fa3aebd7b2a0 (diff) | |
download | wireshark-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.c | 10 |
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 }}, |