diff mbox series

USB: gadget: dummy_hcd: switch char * to u8 *

Message ID 20221021064453.3341050-1-gregkh@linuxfoundation.org
State Superseded
Headers show
Series USB: gadget: dummy_hcd: switch char * to u8 * | expand

Commit Message

Greg KH Oct. 21, 2022, 6:44 a.m. UTC
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.

Cc: Felipe Balbi <balbi@kernel.org>
Cc: Jakob Koschel <jakobkoschel@gmail.com>
Cc: Randy Dunlap <rdunlap@infradead.org>
Cc: Ira Weiny <ira.weiny@intel.com>
Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 drivers/usb/gadget/udc/dummy_hcd.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Greg KH Oct. 23, 2022, 4:04 p.m. UTC | #1
On Sun, Oct 23, 2022 at 05:53:19PM +0200, Greg Kroah-Hartman wrote:
> On Fri, Oct 21, 2022 at 10:30:37AM -0700, Linus Torvalds wrote:
> > On Thu, Oct 20, 2022 at 11:44 PM Greg Kroah-Hartman
> > <gregkh@linuxfoundation.org> wrote:
> > >
> > > 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.
> > 
> > I think you might as well also remove the cast that was always a bit odd:
> > 
> >                 buf[0] = (u8)dum->devstatus;
> > 
> > although maybe it's intentional ("look, ma, I'm truncating this
> > value") because 'devstatus' is a 'u16' type?
> 
> (adding Alan as he's the owner of this file now)
> 
> Yes, devstatus is a u16 as that's what the USB spec says it should be,
> but so far only 7 of the lower bits have been used.  I guess to do this
> properly we should also copy the upper 8 bits in to buf[1], eventhough
> in reality it's only ever going to be 0x00 for now.

Along these lines, do we really not have a predefined macro/inline
function that does:
	(value >> 8)
to give you the "high byte" of a 16bit value?  I keep seeing people
write their own macros for this in staging drivers, but I just
attributed that to them not using the correct in-kernel macro, but I
can't seem to find anything at the moment to do this (same with "give me
just the lower 8 bits of a 16bit value").

Am I just blind?

It's not like it's complex or tricky stuff, I just thought we had
something in bits.h or bitops.h or the like.  Oh well...

thanks,

greg k-h
Linus Torvalds Oct. 23, 2022, 4:46 p.m. UTC | #2
On Sun, Oct 23, 2022 at 9:04 AM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> Along these lines, do we really not have a predefined macro/inline
> function that does:
>         (value >> 8)
> to give you the "high byte" of a 16bit value?

No macros like that. And honestly, why would you want a macro that is
more complicated than the operation itself?

But it sounds like what you actually want is just

     put_unaligned_le16(dum->devstatus, buf);

which does both bytes correctly (and turns into a plain 16-bit store
on sane architectures)..

               Linus
diff mbox series

Patch

diff --git a/drivers/usb/gadget/udc/dummy_hcd.c b/drivers/usb/gadget/udc/dummy_hcd.c
index 899ac9f9c279..774781968e55 100644
--- a/drivers/usb/gadget/udc/dummy_hcd.c
+++ b/drivers/usb/gadget/udc/dummy_hcd.c
@@ -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
 			 * 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);