Re: [PATCH] staging: rtl8712: fix uninit-value "data" and "mac"

From: Dan Carpenter
Date: Thu Apr 14 2022 - 12:08:03 EST


On Thu, Apr 14, 2022 at 10:12:23PM +0800, Wang Cheng wrote:
> Due to the case that "requesttype == 0x01 && status <= 0"
> isn't handled in r8712_usbctrl_vendorreq(),
> "data" (drivers/staging/rtl8712/usb_ops.c:32)
> will be returned without initialization.
>
> When "tmpU1b" (drivers/staging/rtl8712/usb_intf.c:395)
> is 0, mac[6] (usb_intf.c:394) won't be initialized,
> which leads to accessing uninit-value on usb_intf.c:541.

These line numbers are sort of useless because everyone is on a
different git hash.

>
> Reported-and-tested-by: syzbot+6f5ecd144854c0d8580b@xxxxxxxxxxxxxxxxxxxxxxxxx
> Signed-off-by: Wang Cheng <wanngchenng@xxxxxxxxx>
> ---
> drivers/staging/rtl8712/usb_intf.c | 6 +++---
> drivers/staging/rtl8712/usb_ops_linux.c | 14 ++++++++------
> 2 files changed, 11 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c
> index ee4c61f85a07..50dcd3ecb685 100644
> --- a/drivers/staging/rtl8712/usb_intf.c
> +++ b/drivers/staging/rtl8712/usb_intf.c
> @@ -538,13 +538,13 @@ static int r871xu_drv_init(struct usb_interface *pusb_intf,
> } else {
> AutoloadFail = false;
> }
> - if (((mac[0] == 0xff) && (mac[1] == 0xff) &&
> + if ((!AutoloadFail) ||
> + ((mac[0] == 0xff) && (mac[1] == 0xff) &&
> (mac[2] == 0xff) && (mac[3] == 0xff) &&
> (mac[4] == 0xff) && (mac[5] == 0xff)) ||
> ((mac[0] == 0x00) && (mac[1] == 0x00) &&
> (mac[2] == 0x00) && (mac[3] == 0x00) &&
> - (mac[4] == 0x00) && (mac[5] == 0x00)) ||
> - (!AutoloadFail)) {
> + (mac[4] == 0x00) && (mac[5] == 0x00))) {
> mac[0] = 0x00;
> mac[1] = 0xe0;
> mac[2] = 0x4c;

This is a separate fix from the rest of the patch. Send it by itself.


> diff --git a/drivers/staging/rtl8712/usb_ops_linux.c b/drivers/staging/rtl8712/usb_ops_linux.c
> index f984a5ab2c6f..e321ca4453ca 100644
> --- a/drivers/staging/rtl8712/usb_ops_linux.c
> +++ b/drivers/staging/rtl8712/usb_ops_linux.c
> @@ -495,12 +495,14 @@ int r8712_usbctrl_vendorreq(struct intf_priv *pintfpriv, u8 request, u16 value,
> }
> status = usb_control_msg(udev, pipe, request, reqtype, value, index,
> pIo_buf, len, 500);
> - if (status > 0) { /* Success this control transfer. */
> - if (requesttype == 0x01) {
> - /* For Control read transfer, we have to copy the read
> - * data from pIo_buf to pdata.
> - */
> - memcpy(pdata, pIo_buf, status);
> + /* For Control read transfer, copy the read data from pIo_buf to pdata
> + * when control transfer success; otherwise init *pdata with 0.
> + */
> + if (requesttype == 0x01) {
> + if (status > 0)
> + memcpy(pdata, pIo_buf, status);
> + else
> + *(u32 *)pdata = 0;
> }

This isn't really correct. In many cases status is "len" is less than 4.
I'm slightly surprised that nothing complains about that as an
uninitialized access. But then another problem is that "status" can be
less than "len".

A better fix instead of setting pdata to zero would be to add error
checking in the callers and then change this code to use
usb_control_msg_send/recv(). Probably just initialize "data" in the
callers as well.

regards,
dan carpenter