USB: gadget: dummy_hcd: switch char * to u8 *
Greg Kroah-Hartman
maintainerPATCH v2 1/1 USB: gadget: dummy_hcd: switch char * to u8 *
The function handle_control_request() casts the urb buffer to a char *, and then treats it like a unsigned char buffer when assigning data to it. On some architectures, "char" is really signed, so let's just properly set this pointer to a u8 to take away any potential problems as that's what is really wanted here.
Use put_unaligned_le16() to copy the full 16bits into the buffer, it's not a problem just yet as only 7 bits are being used here, but this protects us when/if the USB spec changes in the future to define more of these bits.
---
v2: - use put_unaligned_le16() on Linus's recommendation as a simpler and
more obvious way to describe the data being copied here.
- update device: comment based on Alan's review
drivers/usb/gadget/udc/dummy_hcd.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
drivers/usb/gadget/udc/dummy_hcd.c +6 -7
@@ -1740,13 +1740,13 @@ static int handle_control_request(struct dummy_hcd *dum_hcd, struct urb *urb,if (setup->bRequestType == Dev_InRequest || setup->bRequestType == Intf_InRequest || setup->bRequestType == Ep_InRequest) { -char *buf; +u8 *buf;/* -* device: remote wakeup, selfpowered +* device: remote wakeup, selfpowered, LTM, U1, or U2 * interface: nothing * endpoint: halt */ - buf = (char *)urb->transfer_buffer; + buf = urb->transfer_buffer;if (urb->transfer_buffer_length >0 ) {if (setup->bRequestType == Ep_InRequest) { ep2 =find_endpoint (dum, w_index);
@@ -1755,10 +1755,9 @@ static int handle_control_request(struct dummy_hcd *dum_hcd, struct urb *urb,break ; } buf[0 ] = ep2->halted; - }else if (setup->bRequestType == - Dev_InRequest) { - buf[0 ] = (u8 )dum->devstatus; - }else + }else if (setup->bRequestType == Dev_InRequest) +put_unaligned_le16 (dum->devstatus, buf); +else buf[0 ] =0 ; }if (urb->transfer_buffer_length >1 )
Signature · 1 line
2.38.1
Quoted 48 lines · Greg Kroah-Hartman
The function
handle_control_request()casts the urb buffer to a char *, and then treats it like a unsigned char buffer when assigning data to it. On some architectures, "char" is really signed, so let's just properly set this pointer to a u8 to take away any potential problems as that's what is really wanted here.Use
put_unaligned_le16()to copy the full 16bits into the buffer, it's not a problem just yet as only 7 bits are being used here, but this protects us when/if the USB spec changes in the future to define more of these bits.Cc Felipe Balbi <[email protected]>Cc Jakob Koschel <[email protected]>Cc Randy Dunlap <[email protected]>Cc Ira Weiny <[email protected]>Cc Alan Stern <[email protected]>Reported-by Linus Torvalds <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>---
v2: - useput_unaligned_le16()on Linus's recommendation as a simpler and
more obvious way to describe the data being copied here.
- update device: comment based on Alan's reviewdrivers/usb/gadget/udc/dummy_hcd.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)drivers/usb/gadget/udc/dummy_hcd.c +3
-3@@ -1740,13 +1740,13 @@ static int handle_control_request(struct dummy_hcd *dum_hcd, struct urb *urb,if (setup->bRequestType == Dev_InRequest || setup->bRequestType == Intf_InRequest || setup->bRequestType == Ep_InRequest) { -char *buf; +u8 *buf;/* -* device: remote wakeup, selfpowered +* device: remote wakeup, selfpowered, LTM, U1, or U2 * interface: nothing * endpoint: halt */ - buf = (char *)urb->transfer_buffer; + buf = urb->transfer_buffer;if (urb->transfer_buffer_length >0 ) {if (setup->bRequestType == Ep_InRequest) { ep2 =find_endpoint (dum, w_index);
drivers/usb/gadget/udc/dummy_hcd.c static int handle_control_request(struct dummy_hcd *dum_hcd, struct urb *urb, · line 1759
Quoted 9 lines
drivers/usb/gadget/udc/dummy_hcd.c +2
-4@@ -1755,10 +1755,9 @@ static int handle_control_request(struct dummy_hcd *dum_hcd, struct urb *urb,break ; } buf[0 ] = ep2->halted; - }else if (setup->bRequestType == - Dev_InRequest) { - buf[0 ] = (u8 )dum->devstatus; - }else + }else if (setup->bRequestType == Dev_InRequest) +put_unaligned_le16 (dum->devstatus, buf);
This is tempting but wrong. At this point we haven't checked how big the transfer_buffer is; if it is only one byte long then this call will overflow the buffer. Notice the "if" statement three lines below.
Alan Stern
Quoted 7 lines
drivers/usb/gadget/udc/dummy_hcd.c +1
-0+else buf[0 ] =0 ; }if (urb->transfer_buffer_length >1 )Signature · 1 line
2.38.1
Greg Kroah-Hartman
maintainerQuoted 54 lines · Alan Stern
Quoted 53 lines · Greg Kroah-Hartman
The function
handle_control_request()casts the urb buffer to a char *, and then treats it like a unsigned char buffer when assigning data to it. On some architectures, "char" is really signed, so let's just properly set this pointer to a u8 to take away any potential problems as that's what is really wanted here.Use
put_unaligned_le16()to copy the full 16bits into the buffer, it's not a problem just yet as only 7 bits are being used here, but this protects us when/if the USB spec changes in the future to define more of these bits.Cc Felipe Balbi <[email protected]>Cc Jakob Koschel <[email protected]>Cc Randy Dunlap <[email protected]>Cc Ira Weiny <[email protected]>Cc Alan Stern <[email protected]>Reported-by Linus Torvalds <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>---
v2: - useput_unaligned_le16()on Linus's recommendation as a simpler and
more obvious way to describe the data being copied here.
- update device: comment based on Alan's reviewdrivers/usb/gadget/udc/dummy_hcd.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)drivers/usb/gadget/udc/dummy_hcd.c +3
-5@@ -1740,13 +1740,13 @@ static int handle_control_request(struct dummy_hcd *dum_hcd, struct urb *urb,if (setup->bRequestType == Dev_InRequest || setup->bRequestType == Intf_InRequest || setup->bRequestType == Ep_InRequest) { -char *buf; +u8 *buf;/* -* device: remote wakeup, selfpowered +* device: remote wakeup, selfpowered, LTM, U1, or U2 * interface: nothing * endpoint: halt */ - buf = (char *)urb->transfer_buffer; + buf = urb->transfer_buffer;if (urb->transfer_buffer_length >0 ) {if (setup->bRequestType == Ep_InRequest) { ep2 =find_endpoint (dum, w_index);@@ -1755,10 +1755,9 @@ static int handle_control_request(struct dummy_hcd *dum_hcd, struct urb *urb,break ; } buf[0 ] = ep2->halted; - }else if (setup->bRequestType == - Dev_InRequest) {
Quoted 8 lines
drivers/usb/gadget/udc/dummy_hcd.c static int handle_control_request(struct dummy_hcd *dum_hcd, struct urb *urb, · line 1759
Quoted 4 lines
drivers/usb/gadget/udc/dummy_hcd.c +2
-2- buf[0 ] = (u8 )dum->devstatus; - }else + }else if (setup->bRequestType == Dev_InRequest) +put_unaligned_le16 (dum->devstatus, buf);This is tempting but wrong. At this point we haven't checked how big the
transfer_bufferis; if it is only one byte long then this call will overflow the buffer. Notice the "if" statement three lines below.
Ick, good catch. I'll redo this again...
thanks,
greg k-h