summaryrefslogtreecommitdiff
path: root/epan/dissectors
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors')
-rw-r--r--epan/dissectors/packet-usb.c41
-rw-r--r--epan/dissectors/packet-usb.h6
2 files changed, 23 insertions, 24 deletions
diff --git a/epan/dissectors/packet-usb.c b/epan/dissectors/packet-usb.c
index ddaabca4fa..cb23e9dcdf 100644
--- a/epan/dissectors/packet-usb.c
+++ b/epan/dissectors/packet-usb.c
@@ -188,6 +188,7 @@ static gint ett_endpoint_bmAttributes = -1;
static gint ett_endpoint_wMaxPacketSize = -1;
static expert_field ei_usb_bLength_even = EI_INIT;
+static expert_field ei_usb_bLength_too_short = EI_INIT;
static expert_field ei_usb_desc_length_invalid = EI_INIT;
static const int *usb_endpoint_fields[] = {
@@ -1271,15 +1272,16 @@ dissect_usb_setup_get_configuration_response(packet_info *pinfo _U_, proto_tree
* for URB_CONTROL_INPUT / GET DESCRIPTOR
*/
-void dissect_usb_descriptor_header(proto_tree *tree,
- tvbuff_t *tvb, int offset,
- value_string_ext *type_val_str)
+proto_item * dissect_usb_descriptor_header(proto_tree *tree,
+ tvbuff_t *tvb, int offset,
+ value_string_ext *type_val_str)
{
guint8 desc_type;
- proto_item *type_item = NULL;
+ proto_item *length_item;
+ proto_item *type_item;
- proto_tree_add_item(tree, hf_usb_bLength,
+ length_item = proto_tree_add_item(tree, hf_usb_bLength,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset++;
@@ -1292,6 +1294,8 @@ void dissect_usb_descriptor_header(proto_tree *tree,
type_val_str = &std_descriptor_type_vals_ext;
proto_item_append_text(type_item, " (%s)",
val_to_str_ext(desc_type, type_val_str, "unknown"));
+
+ return length_item;
}
/* 9.6.2 */
@@ -1533,6 +1537,7 @@ dissect_usb_string_descriptor(packet_info *pinfo _U_, proto_tree *parent_tree,
proto_tree *tree = NULL;
int old_offset = offset;
guint8 len;
+ proto_item *len_item;
if (parent_tree) {
item = proto_tree_add_text(parent_tree, tvb, offset, -1, "STRING DESCRIPTOR");
@@ -1543,8 +1548,6 @@ dissect_usb_string_descriptor(packet_info *pinfo _U_, proto_tree *parent_tree,
/* The USB spec says that the languages / the string are UTF16 and not
0-terminated, i.e. the length field must contain an even number */
if (len & 0x1) {
- proto_item *len_item;
-
/* bLength */
len_item = proto_tree_add_item(tree, hf_usb_bLength, tvb, offset, 1, ENC_LITTLE_ENDIAN);
expert_add_info(pinfo, len_item, &ei_usb_bLength_even);
@@ -1553,10 +1556,15 @@ dissect_usb_string_descriptor(packet_info *pinfo _U_, proto_tree *parent_tree,
proto_tree_add_item(tree, hf_usb_bDescriptorType, tvb, offset+1, 1, ENC_LITTLE_ENDIAN);
}
else
- dissect_usb_descriptor_header(tree, tvb, offset, NULL);
-
+ len_item = dissect_usb_descriptor_header(tree, tvb, offset, NULL);
offset += 2;
+ /* Report an error, and give up, if the length is < 2 */
+ if (len < 2) {
+ expert_add_info(pinfo, len_item, &ei_usb_bLength_too_short);
+ return offset;
+ }
+
if (!usb_trans_info->u.get_descriptor.index) {
/* list of languanges */
while(len>(offset-old_offset)) {
@@ -1565,18 +1573,8 @@ dissect_usb_string_descriptor(packet_info *pinfo _U_, proto_tree *parent_tree,
offset+=2;
}
} else {
- char *str;
- guint8 str_len;
-
- /* Make sure that tvb_get_unicode_string() gets an even
- string length even if the length field contains an (invalid)
- odd number.
- */
- str_len = (len-2) & ~0x1;
-
- /* unicode string */
- str = tvb_get_unicode_string(wmem_packet_scope(), tvb, offset, str_len, ENC_LITTLE_ENDIAN);
- proto_tree_add_string(tree, hf_usb_bString, tvb, offset, len-2, str);
+ /* UTF-16 string */
+ proto_tree_add_item(tree, hf_usb_bString, tvb, offset, len-2, ENC_UTF_16 | ENC_LITTLE_ENDIAN);
offset += len-2;
}
@@ -4122,6 +4120,7 @@ proto_register_usb(void)
static ei_register_info ei[] = {
{ &ei_usb_bLength_even, { "usb.bLength.even", PI_PROTOCOL, PI_WARN, "Invalid STRING DESCRIPTOR Length (must be even)", EXPFILL }},
+ { &ei_usb_bLength_too_short, { "usb.bLength.too_short", PI_MALFORMED, PI_ERROR, "Invalid STRING DESCRIPTOR Length (must be 2 or larger)", EXPFILL }},
{ &ei_usb_desc_length_invalid, { "usb.desc_length.invalid", PI_MALFORMED, PI_ERROR, "Invalid descriptor length", EXPFILL }},
};
diff --git a/epan/dissectors/packet-usb.h b/epan/dissectors/packet-usb.h
index 19d0afbeab..fda56a8b06 100644
--- a/epan/dissectors/packet-usb.h
+++ b/epan/dissectors/packet-usb.h
@@ -188,9 +188,9 @@ typedef struct _usb_tap_data_t {
usb_conv_info_t *get_usb_iface_conv_info(packet_info *pinfo, guint8 interface_num);
-void dissect_usb_descriptor_header(proto_tree *tree,
- tvbuff_t *tvb, int offset,
- value_string_ext *type_val_str);
+proto_item * dissect_usb_descriptor_header(proto_tree *tree,
+ tvbuff_t *tvb, int offset,
+ value_string_ext *type_val_str);
void dissect_usb_endpoint_address(proto_tree *tree, tvbuff_t *tvb, int offset);
#endif