aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-rtp.c
diff options
context:
space:
mode:
authorJohn Thacker <johnthacker@gmail.com>2021-11-01 21:07:12 -0400
committerWireshark GitLab Utility <gerald+gitlab-utility@wireshark.org>2021-11-04 05:29:02 +0000
commitdc22cb1b89a5fc9d8e96d49c6886cf3bc0a70040 (patch)
tree6a0a226838423d104d07e1470a90001db6ad0c65 /epan/dissectors/packet-rtp.c
parent0b13ad6d95ee79f6879940e51bd5a94c797446f8 (diff)
RTP: Strengthen heuristics
Strengthen the heuristics according to Appendix A.1 of RFC 3550: Reject if the packet isn't long enough to fit the fixed header, including the CSRCs if present. Reject if the packet isn't long enough to fit the extension header. Reject if the packet isn't long enough to fit the padding, if we have all the packet. Reject the payload types reserved for RTCP conflict. Most of these lead to malformed packet error if dissected anyway, which can still be done via other methods (SDP, Decode As, etc.)
Diffstat (limited to 'epan/dissectors/packet-rtp.c')
-rw-r--r--epan/dissectors/packet-rtp.c47
1 files changed, 45 insertions, 2 deletions
diff --git a/epan/dissectors/packet-rtp.c b/epan/dissectors/packet-rtp.c
index 90e34e0749..66b69f8ac7 100644
--- a/epan/dissectors/packet-rtp.c
+++ b/epan/dissectors/packet-rtp.c
@@ -1195,9 +1195,14 @@ rtp_add_address(packet_info *pinfo, const port_type ptype, address *addr, int po
static gboolean
dissect_rtp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
{
- guint8 octet1;
- unsigned int version;
+ guint8 octet1, octet2;
+ unsigned int version, payload_type;
unsigned int offset = 0;
+ gint padding_count;
+
+ if (tvb_captured_length_remaining(tvb, offset) < 2) {
+ return FALSE;
+ }
/* Get the fields in the first octet */
octet1 = tvb_get_guint8( tvb, offset );
@@ -1235,6 +1240,44 @@ dissect_rtp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data
return FALSE;
}
+ octet2 = tvb_get_guint8( tvb, offset + 1 );
+ payload_type = RTP_PAYLOAD_TYPE( octet2 );
+
+ if (payload_type >= 72 && payload_type <= 76) {
+ /* XXX: This range is definitely excluded by RFCs 3550, 3551.
+ * There's an argument, per RFC 5761, for expanding the
+ * excluded range to [FIRST_RTCP_CONFLICT_PAYLOAD_TYPE,
+ * LAST_RTCP_CONFLICT_PAYLOAD_TYPE] in the heuristic dissector,
+ * leaving those values only when specificed by other means
+ * (SDP, Decode As, etc.)
+ */
+ return FALSE;
+ }
+
+ /* Skip fixed header */
+ offset += 12;
+
+ offset += 4 * RTP_CSRC_COUNT( octet1 );
+ if (RTP_EXTENSION( octet1 )) {
+ if (tvb_captured_length_remaining(tvb, offset) < 4) {
+ return FALSE;
+ }
+ offset += 4 + 4*tvb_get_guint16(tvb, offset+2, ENC_BIG_ENDIAN);
+ }
+ if (tvb_reported_length(tvb) < offset) {
+ return FALSE;
+ }
+ if (RTP_PADDING( octet1 )) {
+ if (tvb_captured_length(tvb) == tvb_reported_length(tvb)) {
+ /* We can test the padding if the last octet is present. */
+ padding_count = tvb_get_guint8(tvb, tvb_reported_length(tvb) - 1);
+ if (tvb_reported_length_remaining(tvb, offset) < padding_count ||
+ padding_count == 0) {
+ return FALSE;
+ }
+ }
+ }
+
/* Create a conversation in case none exists so as to allow reassembly code to work */
if (!find_conversation(pinfo->num, &pinfo->net_dst, &pinfo->net_src, conversation_pt_to_endpoint_type(pinfo->ptype),
pinfo->destport, pinfo->srcport, NO_ADDR2)) {