diff mbox series

usb: mtu3: Fix possible use-before-initialization bug

Message ID CA+UBctDxfb6+70+hzuXJ-gwb65E0uoNzXYEhpJT92sXr2CE7OA@mail.gmail.com
State New
Headers show
Series usb: mtu3: Fix possible use-before-initialization bug | expand

Commit Message

Yu Hao July 4, 2023, 11:25 p.m. UTC
The struct usb_ctrlrequest setup should be initialized in the function
ep0_read_setup(mtu, &setup). However, inside that function,
the variable count could be 0 and the struct usb_ctrlrequest setup
is not initialized. But there is a read for setup.bRequestType.

Signed-off-by: Yu Hao <yhao016@ucr.edu>
---
 drivers/usb/mtu3/mtu3_gadget_ep0.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

Herve Codina July 5, 2023, 6:06 a.m. UTC | #1
Hi Yu,

On Tue, 4 Jul 2023 16:25:50 -0700
Yu Hao <yhao016@ucr.edu> wrote:

> The struct usb_ctrlrequest setup should be initialized in the function
> ep0_read_setup(mtu, &setup). However, inside that function,
> the variable count could be 0 and the struct usb_ctrlrequest setup
> is not initialized. But there is a read for setup.bRequestType.
> 
> Signed-off-by: Yu Hao <yhao016@ucr.edu>
> ---
>  drivers/usb/mtu3/mtu3_gadget_ep0.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/mtu3/mtu3_gadget_ep0.c
> b/drivers/usb/mtu3/mtu3_gadget_ep0.c
> index e4fd1bb14a55..67034fa515d0 100644
> --- a/drivers/usb/mtu3/mtu3_gadget_ep0.c
> +++ b/drivers/usb/mtu3/mtu3_gadget_ep0.c
> @@ -638,7 +638,7 @@ static int ep0_handle_setup(struct mtu3 *mtu)
>  __releases(mtu->lock)
>  __acquires(mtu->lock)
>  {
> -   struct usb_ctrlrequest setup;
> +   struct usb_ctrlrequest setup = {};
>     struct mtu3_request *mreq;
>     int handled = 0;
> 

Looks strange to me because, if ep0_read_setup() cannot read the setup data
why don't we simply abort the operation ?

With setup = {}, the following test is true:
  if ((setup.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
	handled = handle_standard_request(mtu, &setup);

handle_standard_request() is called and supposes an USB_REQ_GET_STATUS
(0x00) request:
   case USB_REQ_GET_STATUS:
	handled = ep0_get_status(mtu, setup);
	break;

Then ep0_get_status() supposes USB_RECIP_DEVICE (0x00) and performs some
operation sending the data related to the GET_STATUS.

All of these are not correct as the setup data that triggered this sequence
was never received.
Aborting the operation if ep0_read_setup() cannot read the setup data seems
better to me.

Best regards,
Hervé
Greg Kroah-Hartman July 5, 2023, 7:16 a.m. UTC | #2
On Tue, Jul 04, 2023 at 04:25:50PM -0700, Yu Hao wrote:
> The struct usb_ctrlrequest setup should be initialized in the function
> ep0_read_setup(mtu, &setup). However, inside that function,
> the variable count could be 0 and the struct usb_ctrlrequest setup
> is not initialized. But there is a read for setup.bRequestType.
> 
> Signed-off-by: Yu Hao <yhao016@ucr.edu>
> ---
>  drivers/usb/mtu3/mtu3_gadget_ep0.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/drivers/usb/mtu3/mtu3_gadget_ep0.c
> b/drivers/usb/mtu3/mtu3_gadget_ep0.c
> index e4fd1bb14a55..67034fa515d0 100644
> --- a/drivers/usb/mtu3/mtu3_gadget_ep0.c
> +++ b/drivers/usb/mtu3/mtu3_gadget_ep0.c
> @@ -638,7 +638,7 @@ static int ep0_handle_setup(struct mtu3 *mtu)
>  __releases(mtu->lock)
>  __acquires(mtu->lock)
>  {
> -   struct usb_ctrlrequest setup;
> +   struct usb_ctrlrequest setup = {};
>     struct mtu3_request *mreq;
>     int handled = 0;
> 
> -- 
> 2.34.1

Hi,

This is the friendly patch-bot of Greg Kroah-Hartman.  You have sent him
a patch that has triggered this response.  He used to manually respond
to these common problems, but in order to save his sanity (he kept
writing the same thing over and over, yet to different people), I was
created.  Hopefully you will not take offence and will fix the problem
in your patch and resubmit it so that it can be accepted into the Linux
kernel tree.

You are receiving this message because of the following common error(s)
as indicated below:

- Your patch is malformed (tabs converted to spaces, linewrapped, etc.)
  and can not be applied.  Please read the file,
  Documentation/process/email-clients.rst in order to fix this.

If you wish to discuss this problem further, or you have questions about
how to resolve this issue, please feel free to respond to this email and
Greg will reply once he has dug out from the pending patches received
from other developers.

thanks,

greg k-h's patch email bot
Yu Hao July 10, 2023, 12:48 a.m. UTC | #3
Hi Hervé,

Thanks for the comments. How about this patch?
---
 drivers/usb/mtu3/mtu3_gadget_ep0.c | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/mtu3/mtu3_gadget_ep0.c
b/drivers/usb/mtu3/mtu3_gadget_ep0.c
index e4fd1bb14a55..af2884943c2a 100644
--- a/drivers/usb/mtu3/mtu3_gadget_ep0.c
+++ b/drivers/usb/mtu3/mtu3_gadget_ep0.c
@@ -600,7 +600,7 @@ static void ep0_tx_state(struct mtu3 *mtu)
        mtu3_readl(mtu->mac_base, U3D_EP0CSR));
 }

-static void ep0_read_setup(struct mtu3 *mtu, struct usb_ctrlrequest *setup)
+static int ep0_read_setup(struct mtu3 *mtu, struct usb_ctrlrequest *setup)
 {
    struct mtu3_request *mreq;
    u32 count;
@@ -608,6 +608,8 @@ static void ep0_read_setup(struct mtu3 *mtu,
struct usb_ctrlrequest *setup)

    csr = mtu3_readl(mtu->mac_base, U3D_EP0CSR) & EP0_W1C_BITS;
    count = mtu3_readl(mtu->mac_base, U3D_RXCOUNT0);
+   if (count == 0)
+       return -EINVAL;

    ep0_read_fifo(mtu->ep0, (u8 *)setup, count);

@@ -642,7 +644,8 @@ __acquires(mtu->lock)
    struct mtu3_request *mreq;
    int handled = 0;

-   ep0_read_setup(mtu, &setup);
+   if (ep0_read_setup(mtu, &setup))
+       return -EINVAL;
    trace_mtu3_handle_setup(&setup);

    if ((setup.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
@@ -764,7 +767,9 @@ irqreturn_t mtu3_ep0_isr(struct mtu3 *mtu)
            break;
        }

-       ep0_handle_setup(mtu);
+       if (ep0_handle_setup(mtu))
+           break;
+
        ret = IRQ_HANDLED;
        break;
    default:
Herve Codina July 10, 2023, 6:25 a.m. UTC | #4
Hi Yu,

On Sun, 9 Jul 2023 17:48:15 -0700
Yu Hao <yhao016@ucr.edu> wrote:

> Hi Hervé,
> 
> Thanks for the comments. How about this patch?
> ---
>  drivers/usb/mtu3/mtu3_gadget_ep0.c | 11 ++++++++---
>  1 file changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/usb/mtu3/mtu3_gadget_ep0.c
> b/drivers/usb/mtu3/mtu3_gadget_ep0.c
> index e4fd1bb14a55..af2884943c2a 100644
> --- a/drivers/usb/mtu3/mtu3_gadget_ep0.c
> +++ b/drivers/usb/mtu3/mtu3_gadget_ep0.c
> @@ -600,7 +600,7 @@ static void ep0_tx_state(struct mtu3 *mtu)
>         mtu3_readl(mtu->mac_base, U3D_EP0CSR));
>  }
> 
> -static void ep0_read_setup(struct mtu3 *mtu, struct usb_ctrlrequest *setup)
> +static int ep0_read_setup(struct mtu3 *mtu, struct usb_ctrlrequest *setup)
>  {
>     struct mtu3_request *mreq;
>     u32 count;
> @@ -608,6 +608,8 @@ static void ep0_read_setup(struct mtu3 *mtu,
> struct usb_ctrlrequest *setup)
> 
>     csr = mtu3_readl(mtu->mac_base, U3D_EP0CSR) & EP0_W1C_BITS;
>     count = mtu3_readl(mtu->mac_base, U3D_RXCOUNT0);
> +   if (count == 0)
> +       return -EINVAL;

'count' should be tested against sizeof(*setup). Indeed, we need to have a
setup data packet in the fifo.

What do you think about:
if (count < sizef(*setup))
	return -EINVAL;

> 
>     ep0_read_fifo(mtu->ep0, (u8 *)setup, count);
> 
> @@ -642,7 +644,8 @@ __acquires(mtu->lock)
>     struct mtu3_request *mreq;
>     int handled = 0;
> 
> -   ep0_read_setup(mtu, &setup);
> +   if (ep0_read_setup(mtu, &setup))
> +       return -EINVAL;

Forward the error code to the caller ?

ret = ep0_read_setup(mtu, &setup)
if (ret < 0)
	return ret;


>     trace_mtu3_handle_setup(&setup);
> 
>     if ((setup.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
> @@ -764,7 +767,9 @@ irqreturn_t mtu3_ep0_isr(struct mtu3 *mtu)
>             break;
>         }
> 
> -       ep0_handle_setup(mtu);
> +       if (ep0_handle_setup(mtu))
> +           break;
> +

Ok

>         ret = IRQ_HANDLED;
>         break;
>     default:

Be careful, your patch is wrongly indented.
tabs replaced by 4 spaces. You need to keep tabs.

Regards,
Hervé Codina
Chunfeng Yun (云春峰) July 11, 2023, 8:40 a.m. UTC | #5
On Sun, 2023-07-09 at 17:48 -0700, Yu Hao wrote:
>  	 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>  Hi Hervé,
> 
> Thanks for the comments. How about this patch?
> ---
>  drivers/usb/mtu3/mtu3_gadget_ep0.c | 11 ++++++++---
>  1 file changed, 8 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/usb/mtu3/mtu3_gadget_ep0.c
> b/drivers/usb/mtu3/mtu3_gadget_ep0.c
> index e4fd1bb14a55..af2884943c2a 100644
> --- a/drivers/usb/mtu3/mtu3_gadget_ep0.c
> +++ b/drivers/usb/mtu3/mtu3_gadget_ep0.c
> @@ -600,7 +600,7 @@ static void ep0_tx_state(struct mtu3 *mtu)
>         mtu3_readl(mtu->mac_base, U3D_EP0CSR));
>  }
> 
> -static void ep0_read_setup(struct mtu3 *mtu, struct usb_ctrlrequest
> *setup)
> +static int ep0_read_setup(struct mtu3 *mtu, struct usb_ctrlrequest
> *setup)
>  {
>     struct mtu3_request *mreq;
>     u32 count;
> @@ -608,6 +608,8 @@ static void ep0_read_setup(struct mtu3 *mtu,
> struct usb_ctrlrequest *setup)
> 
>     csr = mtu3_readl(mtu->mac_base, U3D_EP0CSR) & EP0_W1C_BITS;
>     count = mtu3_readl(mtu->mac_base, U3D_RXCOUNT0);
> +   if (count == 0)
> +       return -EINVAL;
> 
Which SoC encounter this issue?

if there is no data in fifo, no interrupt will arise, so don't read
setup packet.


>     ep0_read_fifo(mtu->ep0, (u8 *)setup, count);
> 
> @@ -642,7 +644,8 @@ __acquires(mtu->lock)
>     struct mtu3_request *mreq;
>     int handled = 0;
> 
> -   ep0_read_setup(mtu, &setup);
> +   if (ep0_read_setup(mtu, &setup))
> +       return -EINVAL;
>     trace_mtu3_handle_setup(&setup);
> 
>     if ((setup.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
> @@ -764,7 +767,9 @@ irqreturn_t mtu3_ep0_isr(struct mtu3 *mtu)
>             break;
>         }
> 
> -       ep0_handle_setup(mtu);
> +       if (ep0_handle_setup(mtu))
> +           break;
> +
>         ret = IRQ_HANDLED;
>         break;
>     default:
Chunfeng Yun (云春峰) July 11, 2023, 8:48 a.m. UTC | #6
On Mon, 2023-07-10 at 08:25 +0200, Herve Codina wrote:
>  	 
> External email : Please do not click links or open attachments until
> you have verified the sender or the content.
>  Hi Yu,
> 
> On Sun, 9 Jul 2023 17:48:15 -0700
> Yu Hao <yhao016@ucr.edu> wrote:
> 
> > Hi Hervé,
> > 
> > Thanks for the comments. How about this patch?
> > ---
> >  drivers/usb/mtu3/mtu3_gadget_ep0.c | 11 ++++++++---
> >  1 file changed, 8 insertions(+), 3 deletions(-)
> > 
> > diff --git a/drivers/usb/mtu3/mtu3_gadget_ep0.c
> > b/drivers/usb/mtu3/mtu3_gadget_ep0.c
> > index e4fd1bb14a55..af2884943c2a 100644
> > --- a/drivers/usb/mtu3/mtu3_gadget_ep0.c
> > +++ b/drivers/usb/mtu3/mtu3_gadget_ep0.c
> > @@ -600,7 +600,7 @@ static void ep0_tx_state(struct mtu3 *mtu)
> >         mtu3_readl(mtu->mac_base, U3D_EP0CSR));
> >  }
> > 
> > -static void ep0_read_setup(struct mtu3 *mtu, struct
> usb_ctrlrequest *setup)
> > +static int ep0_read_setup(struct mtu3 *mtu, struct usb_ctrlrequest
> *setup)
> >  {
> >     struct mtu3_request *mreq;
> >     u32 count;
> > @@ -608,6 +608,8 @@ static void ep0_read_setup(struct mtu3 *mtu,
> > struct usb_ctrlrequest *setup)
> > 
> >     csr = mtu3_readl(mtu->mac_base, U3D_EP0CSR) & EP0_W1C_BITS;
> >     count = mtu3_readl(mtu->mac_base, U3D_RXCOUNT0);
> > +   if (count == 0)
> > +       return -EINVAL;
> 
> 'count' should be tested against sizeof(*setup). Indeed, we need to
> have a
> setup data packet in the fifo.
> 
> What do you think about:
> if (count < sizef(*setup))
> return -EINVAL;
before call this function, already check the data length in fifo, it
should be 8 bytes.
see mtu3_ep0_isr(), about line 761. 

I think no need this patch

Thanks a lot

> 
> > 
> >     ep0_read_fifo(mtu->ep0, (u8 *)setup, count);
> > 
> > @@ -642,7 +644,8 @@ __acquires(mtu->lock)
> >     struct mtu3_request *mreq;
> >     int handled = 0;
> > 
> > -   ep0_read_setup(mtu, &setup);
> > +   if (ep0_read_setup(mtu, &setup))
> > +       return -EINVAL;
> 
> Forward the error code to the caller ?
> 
> ret = ep0_read_setup(mtu, &setup)
> if (ret < 0)
> return ret;
> 
> 
> >     trace_mtu3_handle_setup(&setup);
> > 
> >     if ((setup.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
> > @@ -764,7 +767,9 @@ irqreturn_t mtu3_ep0_isr(struct mtu3 *mtu)
> >             break;
> >         }
> > 
> > -       ep0_handle_setup(mtu);
> > +       if (ep0_handle_setup(mtu))
> > +           break;
> > +
> 
> Ok
> 
> >         ret = IRQ_HANDLED;
> >         break;
> >     default:
> 
> Be careful, your patch is wrongly indented.
> tabs replaced by 4 spaces. You need to keep tabs.
> 
> Regards,
> Hervé Codina
>
Herve Codina July 11, 2023, 9:41 a.m. UTC | #7
Hi Chunfeng,

On Tue, 11 Jul 2023 08:48:35 +0000
Chunfeng Yun (云春峰) <Chunfeng.Yun@mediatek.com> wrote:

> On Mon, 2023-07-10 at 08:25 +0200, Herve Codina wrote:
> >  	 
> > External email : Please do not click links or open attachments until
> > you have verified the sender or the content.
> >  Hi Yu,
> > 
> > On Sun, 9 Jul 2023 17:48:15 -0700
> > Yu Hao <yhao016@ucr.edu> wrote:
> >   
> > > Hi Hervé,
> > > 
> > > Thanks for the comments. How about this patch?
> > > ---
> > >  drivers/usb/mtu3/mtu3_gadget_ep0.c | 11 ++++++++---
> > >  1 file changed, 8 insertions(+), 3 deletions(-)
> > > 
> > > diff --git a/drivers/usb/mtu3/mtu3_gadget_ep0.c
> > > b/drivers/usb/mtu3/mtu3_gadget_ep0.c
> > > index e4fd1bb14a55..af2884943c2a 100644
> > > --- a/drivers/usb/mtu3/mtu3_gadget_ep0.c
> > > +++ b/drivers/usb/mtu3/mtu3_gadget_ep0.c
> > > @@ -600,7 +600,7 @@ static void ep0_tx_state(struct mtu3 *mtu)
> > >         mtu3_readl(mtu->mac_base, U3D_EP0CSR));
> > >  }
> > > 
> > > -static void ep0_read_setup(struct mtu3 *mtu, struct  
> > usb_ctrlrequest *setup)  
> > > +static int ep0_read_setup(struct mtu3 *mtu, struct usb_ctrlrequest  
> > *setup)  
> > >  {
> > >     struct mtu3_request *mreq;
> > >     u32 count;
> > > @@ -608,6 +608,8 @@ static void ep0_read_setup(struct mtu3 *mtu,
> > > struct usb_ctrlrequest *setup)
> > > 
> > >     csr = mtu3_readl(mtu->mac_base, U3D_EP0CSR) & EP0_W1C_BITS;
> > >     count = mtu3_readl(mtu->mac_base, U3D_RXCOUNT0);
> > > +   if (count == 0)
> > > +       return -EINVAL;  
> > 
> > 'count' should be tested against sizeof(*setup). Indeed, we need to
> > have a
> > setup data packet in the fifo.
> > 
> > What do you think about:
> > if (count < sizef(*setup))
> > return -EINVAL;  
> before call this function, already check the data length in fifo, it
> should be 8 bytes.
> see mtu3_ep0_isr(), about line 761.

Indeed, I missed that point.
Thanks for pointing it.

Regards,
Hervé

> 
> I think no need this patch
> 
> Thanks a lot
> 
> >   
> > > 
> > >     ep0_read_fifo(mtu->ep0, (u8 *)setup, count);
> > > 
> > > @@ -642,7 +644,8 @@ __acquires(mtu->lock)
> > >     struct mtu3_request *mreq;
> > >     int handled = 0;
> > > 
> > > -   ep0_read_setup(mtu, &setup);
> > > +   if (ep0_read_setup(mtu, &setup))
> > > +       return -EINVAL;  
> > 
> > Forward the error code to the caller ?
> > 
> > ret = ep0_read_setup(mtu, &setup)
> > if (ret < 0)
> > return ret;
> > 
> >   
> > >     trace_mtu3_handle_setup(&setup);
> > > 
> > >     if ((setup.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD)
> > > @@ -764,7 +767,9 @@ irqreturn_t mtu3_ep0_isr(struct mtu3 *mtu)
> > >             break;
> > >         }
> > > 
> > > -       ep0_handle_setup(mtu);
> > > +       if (ep0_handle_setup(mtu))
> > > +           break;
> > > +  
> > 
> > Ok
> >   
> > >         ret = IRQ_HANDLED;
> > >         break;
> > >     default:  
> > 
> > Be careful, your patch is wrongly indented.
> > tabs replaced by 4 spaces. You need to keep tabs.
> > 
> > Regards,
> > Hervé Codina
> >
diff mbox series

Patch

diff --git a/drivers/usb/mtu3/mtu3_gadget_ep0.c
b/drivers/usb/mtu3/mtu3_gadget_ep0.c
index e4fd1bb14a55..67034fa515d0 100644
--- a/drivers/usb/mtu3/mtu3_gadget_ep0.c
+++ b/drivers/usb/mtu3/mtu3_gadget_ep0.c
@@ -638,7 +638,7 @@  static int ep0_handle_setup(struct mtu3 *mtu)
 __releases(mtu->lock)
 __acquires(mtu->lock)
 {
-   struct usb_ctrlrequest setup;
+   struct usb_ctrlrequest setup = {};
    struct mtu3_request *mreq;
    int handled = 0;