summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Hanselmann <public@hansmi.ch>2021-01-25 21:19:25 +0100
committerFrediano Ziglio <freddy77@gmail.com>2021-01-28 20:18:31 +0000
commit36cb4a448f7b19430cb0f12e045aa5ae6b10fcae (patch)
tree11228bc5b8104624ab4a325e312abad8a3cb834d
parente3f3c98e3af58f70358402b08b1ff61fa4504cf6 (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.c7
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;