diff options
author | Michael Hanselmann <public@hansmi.ch> | 2021-01-25 21:19:25 +0100 |
---|---|---|
committer | Frediano Ziglio <freddy77@gmail.com> | 2021-01-28 20:18:31 +0000 |
commit | 36cb4a448f7b19430cb0f12e045aa5ae6b10fcae (patch) | |
tree | 11228bc5b8104624ab4a325e312abad8a3cb834d | |
parent | e3f3c98e3af58f70358402b08b1ff61fa4504cf6 (diff) |
Up-cast 16-bit integer before shifting by 16 bits
The usb_redir_bulk_packet_header.length_high field is of type uint16_t.
Shifting it by 16 bits is undefined: "[…] a shift operand value which is
[…] or is greater than or equal to the total number of bits in this
value results in undefined behavior" (explanation from Wikipedia). Also
reported by UBSan:
left shift of 65535 by 16 places cannot be represented in type 'int'
With this change the length is always stored in an uint32_t.
Signed-off-by: Michael Hanselmann <public@hansmi.ch>
Acked-by: Frediano Ziglio <freddy77@gmail.com>
-rw-r--r-- | usbredirparser/usbredirparser.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/usbredirparser/usbredirparser.c b/usbredirparser/usbredirparser.c index 8f239cc..3f822ef 100644 --- a/usbredirparser/usbredirparser.c +++ b/usbredirparser/usbredirparser.c @@ -559,7 +559,8 @@ static int usbredirparser_verify_type_header( struct usbredirparser_priv *parser = (struct usbredirparser_priv *)parser_pub; int command_for_host = 0, expect_extra_data = 0; - int length = 0, ep = -1; + uint32_t length = 0; + int ep = -1; if (parser->flags & usbredirparser_fl_usb_host) { command_for_host = 1; @@ -697,13 +698,13 @@ static int usbredirparser_verify_type_header( usb_redir_cap_32bits_bulk_length) && usbredirparser_peer_has_cap(parser_pub, usb_redir_cap_32bits_bulk_length)) { - length = (bulk_packet->length_high << 16) | bulk_packet->length; + length = (((uint32_t)bulk_packet->length_high) << 16) | bulk_packet->length; } else { length = bulk_packet->length; if (!send) bulk_packet->length_high = 0; } - if ((uint32_t)length > MAX_BULK_TRANSFER_SIZE) { + if (length > MAX_BULK_TRANSFER_SIZE) { ERROR("bulk transfer length exceeds limits %u > %u", (uint32_t)length, MAX_BULK_TRANSFER_SIZE); return 0; |