CVE-2016-5354 (published 2016-08-07T16:59Z)

The USB subsystem in Wireshark 1.12.x before 1.12.12 and 2.x before 2.0.4 mishandles class types, which allows remote attackers to cause a denial of service (application crash) via a crafted packet.

Severity: MEDIUM
CVSS v2 base score: 4.3 (AV:N/AC:M/Au:N/C:N/I:N/A:P)
CVSS v3 base score: 5.9, MEDIUM (CVSS:3.0/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-476
cwe_name: NULL Pointer Dereference
description: The product dereferences a pointer that it expects to be valid but is NULL.
extended_description: 
            
            
            
         
         

Fix information:
repo_url: https://github.com/wireshark/wireshark
commit_details: repo_url: https://github.com/wireshark/wireshark
author: Michael Mann
author_date: 2016-05-01 12:55:23-04:00
msg: Make class "type" for USB conversations.

USB dissectors can't assume that only their class type has been passed around in the conversation.  Make explicit check that class type expected matches the dissector and stop/prevent dissection if there isn't a match.

Bug: 12356
Change-Id: Ib23973a4ebd0fbb51952ffc118daf95e3389a209
Reviewed-on: https://code.wireshark.org/review/15212
Petri-Dish: Michael Mann <mmann78@netscape.net>
Reviewed-by: Martin Kaiser <wireshark@kaiser.cx>
Petri-Dish: Martin Kaiser <wireshark@kaiser.cx>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
repository: repo_url: https://github.com/wireshark/wireshark
repo_name: wireshark/wireshark
description: Read-only mirror of Wireshark's Git repository at https://gitlab.com/wireshark/wireshark. ⚠️ GitHub won't let us disable pull requests. ⚠️ THEY WILL BE IGNORED HERE ⚠️ Upload them at GitLab instead.
repo_language: C
owner: wireshark
file_changes: filename: packet-u3v.c
change_type: ModificationType.MODIFY
diff: @@ -1683,6 +1683,10 @@ dissect_u3v(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
     if (!u3v_conv_info) {
         u3v_conv_info = wmem_new0(wmem_file_scope(), u3v_conv_info_t);
         usb_conv_info->class_data = u3v_conv_info;
+        usb_conv_info->class_data_type = USB_CONV_U3V;
+    } else if (usb_conv_info->class_data_type != USB_CONV_U3V) {
+        /* Don't dissect if another USB type is in the conversation */
+        return 0;
     }
 
     prefix = tvb_get_letohl(tvb, 0);

programming_language: C
filename: packet-usb-audio.c
change_type: ModificationType.MODIFY
diff: @@ -435,8 +435,12 @@ dissect_ac_if_hdr_body(tvbuff_t *tvb, gint offset, packet_info *pinfo _U_,
     if(!audio_conv_info) {
         audio_conv_info = wmem_new(wmem_file_scope(), audio_conv_info_t);
         usb_conv_info->class_data = audio_conv_info;
+        usb_conv_info->class_data_type = USB_CONV_AUDIO;
         /* XXX - set reasonable default values for all components
            that are not filled in by this function */
+    } else if (usb_conv_info->class_data_type != USB_CONV_AUDIO) {
+        /* Don't dissect if another USB type is in the conversation */
+        return 0;
     }
     audio_conv_info->ver_major = ver_major;
     offset += 2;

programming_language: C
filename: packet-usb-masstorage.c
change_type: ModificationType.MODIFY
diff: @@ -199,9 +199,12 @@ dissect_usb_ms_bulk(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
         usb_ms_conv_info->itl=wmem_tree_new(wmem_file_scope());
         usb_ms_conv_info->itlq=wmem_tree_new(wmem_file_scope());
         usb_conv_info->class_data=usb_ms_conv_info;
+        usb_conv_info->class_data_type = USB_CONV_MASS_STORAGE;
+    } else if (usb_conv_info->class_data_type != USB_CONV_MASS_STORAGE) {
+        /* Don't dissect if another USB type is in the conversation */
+        return 0;
     }
 
-
     is_request=(pinfo->srcport==NO_ENDPOINT);
 
     col_set_str(pinfo->cinfo, COL_PROTOCOL, "USBMS");

programming_language: C
filename: packet-usb-video.c
change_type: ModificationType.MODIFY
diff: @@ -1035,6 +1035,10 @@ dissect_usb_video_control_interface_descriptor(proto_tree *parent_tree, tvbuff_t
             video_conv_info = wmem_new(wmem_file_scope(), video_conv_info_t);
             video_conv_info->entities = wmem_tree_new(wmem_file_scope());
             usb_conv_info->class_data = video_conv_info;
+            usb_conv_info->class_data_type = USB_CONV_VIDEO;
+        } else if (usb_conv_info->class_data_type != USB_CONV_VIDEO) {
+            /* Stop dissection if another USB type is in the conversation */
+            return descriptor_len;
         }
 
         entity = (video_entity_t*) wmem_tree_lookup32(video_conv_info->entities, entity_id);

programming_language: C
filename: packet-usb.h
change_type: ModificationType.MODIFY
diff: @@ -90,6 +90,8 @@ typedef struct _usb_trans_info_t {
     guint64 usb_id;
 } usb_trans_info_t;
 
+enum usb_conv_class_data_type {USB_CONV_UNKNOWN = 0, USB_CONV_U3V, USB_CONV_AUDIO, USB_CONV_VIDEO, USB_CONV_MASS_STORAGE};
+
 /* Conversation Structure
  * there is one such structure for each device/endpoint conversation */
 struct _usb_conv_info_t {
@@ -113,7 +115,8 @@ struct _usb_conv_info_t {
     wmem_tree_t *transactions;
     usb_trans_info_t *usb_trans_info; /* pointer to the current transaction */
 
-    void *class_data;	/* private class/id decode data */
+    void *class_data;           /* private class/id decode data */
+    enum usb_conv_class_data_type class_data_type;
 
     wmem_array_t *alt_settings;
 };

programming_language: C