usbnet: make sure no NULL pointer is passed through
authorOliver Neukum <oneukum@suse.com>
Wed, 5 Apr 2017 12:14:39 +0000 (14:14 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 6 Apr 2017 20:17:27 +0000 (13:17 -0700)
Coverity reports:

** CID 751368:  Null pointer dereferences  (FORWARD_NULL)
/drivers/net/usb/usbnet.c: 1925 in __usbnet_read_cmd()

________________________________________________________________________________________________________
*** CID 751368:  Null pointer dereferences  (FORWARD_NULL)
/drivers/net/usb/usbnet.c: 1925 in __usbnet_read_cmd()
1919     EXPORT_SYMBOL(usbnet_link_change);
1920
1921     /*-------------------------------------------------------------------------*/
1922     static int __usbnet_read_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
1923                                 u16 value, u16 index, void *data, u16 size)
1924     {
>>>     CID 751368:  Null pointer dereferences  (FORWARD_NULL)
>>>     Assigning: "buf" = "NULL".
1925            void *buf = NULL;
1926            int err = -ENOMEM;
1927
1928            netdev_dbg(dev->net, "usbnet_read_cmd cmd=0x%02x reqtype=%02x"
1929                       " value=0x%04x index=0x%04x size=%d\n",
1930                       cmd, reqtype, value, index, size);

** CID 751370:  Null pointer dereferences  (FORWARD_NULL)
/drivers/net/usb/usbnet.c: 1952 in __usbnet_write_cmd()

________________________________________________________________________________________________________
*** CID 751370:  Null pointer dereferences  (FORWARD_NULL)
/drivers/net/usb/usbnet.c: 1952 in __usbnet_write_cmd()
1946     }
1947
1948     static int __usbnet_write_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
1949                                  u16 value, u16 index, const void *data,
1950                                  u16 size)
1951     {
>>>     CID 751370:  Null pointer dereferences  (FORWARD_NULL)
>>>     Assigning: "buf" = "NULL".
1952            void *buf = NULL;
1953            int err = -ENOMEM;
1954
1955            netdev_dbg(dev->net, "usbnet_write_cmd cmd=0x%02x reqtype=%02x"
1956                       " value=0x%04x index=0x%04x size=%d\n",
1957                       cmd, reqtype, value, index, size);

** CID 1325026:  Null pointer dereferences  (FORWARD_NULL)
/drivers/net/usb/ch9200.c: 143 in control_write()

It is valid to offer commands without a buffer, but then you need a size
of zero. This should actually be checked.

Signed-off-by: Oliver Neukum <oneukum@suse.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/usb/usbnet.c

index 3de65ea..4532448 100644 (file)
@@ -1929,7 +1929,7 @@ static int __usbnet_read_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
                   " value=0x%04x index=0x%04x size=%d\n",
                   cmd, reqtype, value, index, size);
 
-       if (data) {
+       if (size) {
                buf = kmalloc(size, GFP_KERNEL);
                if (!buf)
                        goto out;
@@ -1938,8 +1938,13 @@ static int __usbnet_read_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
        err = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0),
                              cmd, reqtype, value, index, buf, size,
                              USB_CTRL_GET_TIMEOUT);
-       if (err > 0 && err <= size)
-               memcpy(data, buf, err);
+       if (err > 0 && err <= size) {
+        if (data)
+            memcpy(data, buf, err);
+        else
+            netdev_dbg(dev->net,
+                "Huh? Data requested but thrown away.\n");
+    }
        kfree(buf);
 out:
        return err;
@@ -1960,7 +1965,13 @@ static int __usbnet_write_cmd(struct usbnet *dev, u8 cmd, u8 reqtype,
                buf = kmemdup(data, size, GFP_KERNEL);
                if (!buf)
                        goto out;
-       }
+       } else {
+        if (size) {
+            WARN_ON_ONCE(1);
+            err = -EINVAL;
+            goto out;
+        }
+    }
 
        err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0),
                              cmd, reqtype, value, index, buf, size,