Commit 50591c60 authored by Alexey Khoroshilov's avatar Alexey Khoroshilov Committed by John W. Linville

rsi: fix memory leaks and error handling in rsi_91x_usb

The patch fixes a couple of issues:
- absence of deallocation of rsi_dev->rx_usb_urb[0] in the driver;
- potential NULL pointer dereference because of lack of checks for memory
  allocation success in rsi_init_usb_interface().

By the way, it makes rsi_probe() returning error code instead of 1
and fixes comments regarding returning values.

Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: default avatarAlexey Khoroshilov <khoroshilov@ispras.ru>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 5bc5ca85
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
* @len: Length to be written. * @len: Length to be written.
* @endpoint: Type of endpoint. * @endpoint: Type of endpoint.
* *
* Return: status: 0 on success, -1 on failure. * Return: status: 0 on success, a negative error code on failure.
*/ */
static int rsi_usb_card_write(struct rsi_hw *adapter, static int rsi_usb_card_write(struct rsi_hw *adapter,
void *buf, void *buf,
...@@ -60,7 +60,7 @@ static int rsi_usb_card_write(struct rsi_hw *adapter, ...@@ -60,7 +60,7 @@ static int rsi_usb_card_write(struct rsi_hw *adapter,
* @data: Pointer to the data that has to be written. * @data: Pointer to the data that has to be written.
* @count: Number of multiple bytes to be written. * @count: Number of multiple bytes to be written.
* *
* Return: 0 on success, -1 on failure. * Return: 0 on success, a negative error code on failure.
*/ */
static int rsi_write_multiple(struct rsi_hw *adapter, static int rsi_write_multiple(struct rsi_hw *adapter,
u8 endpoint, u8 endpoint,
...@@ -147,7 +147,7 @@ static int rsi_find_bulk_in_and_out_endpoints(struct usb_interface *interface, ...@@ -147,7 +147,7 @@ static int rsi_find_bulk_in_and_out_endpoints(struct usb_interface *interface,
* @value: Value to be read. * @value: Value to be read.
* @len: length of data to be read. * @len: length of data to be read.
* *
* Return: status: 0 on success, -1 on failure. * Return: status: 0 on success, a negative error code on failure.
*/ */
static int rsi_usb_reg_read(struct usb_device *usbdev, static int rsi_usb_reg_read(struct usb_device *usbdev,
u32 reg, u32 reg,
...@@ -189,7 +189,7 @@ static int rsi_usb_reg_read(struct usb_device *usbdev, ...@@ -189,7 +189,7 @@ static int rsi_usb_reg_read(struct usb_device *usbdev,
* @value: Value to write. * @value: Value to write.
* @len: Length of data to be written. * @len: Length of data to be written.
* *
* Return: status: 0 on success, -1 on failure. * Return: status: 0 on success, a negative error code on failure.
*/ */
static int rsi_usb_reg_write(struct usb_device *usbdev, static int rsi_usb_reg_write(struct usb_device *usbdev,
u32 reg, u32 reg,
...@@ -249,7 +249,7 @@ static void rsi_rx_done_handler(struct urb *urb) ...@@ -249,7 +249,7 @@ static void rsi_rx_done_handler(struct urb *urb)
* rsi_rx_urb_submit() - This function submits the given URB to the USB stack. * rsi_rx_urb_submit() - This function submits the given URB to the USB stack.
* @adapter: Pointer to the adapter structure. * @adapter: Pointer to the adapter structure.
* *
* Return: 0 on success, -1 on failure. * Return: 0 on success, a negative error code on failure.
*/ */
static int rsi_rx_urb_submit(struct rsi_hw *adapter) static int rsi_rx_urb_submit(struct rsi_hw *adapter)
{ {
...@@ -281,7 +281,7 @@ static int rsi_rx_urb_submit(struct rsi_hw *adapter) ...@@ -281,7 +281,7 @@ static int rsi_rx_urb_submit(struct rsi_hw *adapter)
* @data: Pointer to the data that has to be written. * @data: Pointer to the data that has to be written.
* @count: Number of multiple bytes to be written on to the registers. * @count: Number of multiple bytes to be written on to the registers.
* *
* Return: status: 0 on success, -1 on failure. * Return: status: 0 on success, a negative error code on failure.
*/ */
int rsi_usb_write_register_multiple(struct rsi_hw *adapter, int rsi_usb_write_register_multiple(struct rsi_hw *adapter,
u32 addr, u32 addr,
...@@ -331,7 +331,7 @@ int rsi_usb_write_register_multiple(struct rsi_hw *adapter, ...@@ -331,7 +331,7 @@ int rsi_usb_write_register_multiple(struct rsi_hw *adapter,
* @pkt: Pointer to the data to be written on to the card. * @pkt: Pointer to the data to be written on to the card.
* @len: Length of the data to be written on to the card. * @len: Length of the data to be written on to the card.
* *
* Return: 0 on success, -1 on failure. * Return: 0 on success, a negative error code on failure.
*/ */
static int rsi_usb_host_intf_write_pkt(struct rsi_hw *adapter, static int rsi_usb_host_intf_write_pkt(struct rsi_hw *adapter,
u8 *pkt, u8 *pkt,
...@@ -359,6 +359,7 @@ static void rsi_deinit_usb_interface(struct rsi_hw *adapter) ...@@ -359,6 +359,7 @@ static void rsi_deinit_usb_interface(struct rsi_hw *adapter)
struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
rsi_kill_thread(&dev->rx_thread); rsi_kill_thread(&dev->rx_thread);
usb_free_urb(dev->rx_usb_urb[0]);
kfree(adapter->priv->rx_data_pkt); kfree(adapter->priv->rx_data_pkt);
kfree(dev->tx_buffer); kfree(dev->tx_buffer);
} }
...@@ -368,7 +369,7 @@ static void rsi_deinit_usb_interface(struct rsi_hw *adapter) ...@@ -368,7 +369,7 @@ static void rsi_deinit_usb_interface(struct rsi_hw *adapter)
* @adapter: Pointer to the adapter structure. * @adapter: Pointer to the adapter structure.
* @pfunction: Pointer to USB interface structure. * @pfunction: Pointer to USB interface structure.
* *
* Return: 0 on success, -1 on failure. * Return: 0 on success, a negative error code on failure.
*/ */
static int rsi_init_usb_interface(struct rsi_hw *adapter, static int rsi_init_usb_interface(struct rsi_hw *adapter,
struct usb_interface *pfunction) struct usb_interface *pfunction)
...@@ -398,7 +399,15 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter, ...@@ -398,7 +399,15 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter,
} }
rsi_dev->tx_buffer = kmalloc(2048, GFP_KERNEL); rsi_dev->tx_buffer = kmalloc(2048, GFP_KERNEL);
if (!rsi_dev->tx_buffer) {
status = -ENOMEM;
goto fail_tx;
}
rsi_dev->rx_usb_urb[0] = usb_alloc_urb(0, GFP_KERNEL); rsi_dev->rx_usb_urb[0] = usb_alloc_urb(0, GFP_KERNEL);
if (!rsi_dev->rx_usb_urb[0]) {
status = -ENOMEM;
goto fail_rx;
}
rsi_dev->rx_usb_urb[0]->transfer_buffer = adapter->priv->rx_data_pkt; rsi_dev->rx_usb_urb[0]->transfer_buffer = adapter->priv->rx_data_pkt;
rsi_dev->tx_blk_size = 252; rsi_dev->tx_blk_size = 252;
...@@ -413,7 +422,7 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter, ...@@ -413,7 +422,7 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter,
rsi_usb_rx_thread, "RX-Thread"); rsi_usb_rx_thread, "RX-Thread");
if (status) { if (status) {
rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__); rsi_dbg(ERR_ZONE, "%s: Unable to init rx thrd\n", __func__);
goto fail; goto fail_thread;
} }
#ifdef CONFIG_RSI_DEBUGFS #ifdef CONFIG_RSI_DEBUGFS
...@@ -424,8 +433,11 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter, ...@@ -424,8 +433,11 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter,
rsi_dbg(INIT_ZONE, "%s: Enabled the interface\n", __func__); rsi_dbg(INIT_ZONE, "%s: Enabled the interface\n", __func__);
return 0; return 0;
fail: fail_thread:
usb_free_urb(rsi_dev->rx_usb_urb[0]);
fail_rx:
kfree(rsi_dev->tx_buffer); kfree(rsi_dev->tx_buffer);
fail_tx:
kfree(common->rx_data_pkt); kfree(common->rx_data_pkt);
return status; return status;
} }
...@@ -437,7 +449,7 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter, ...@@ -437,7 +449,7 @@ static int rsi_init_usb_interface(struct rsi_hw *adapter,
* @pfunction: Pointer to the USB interface structure. * @pfunction: Pointer to the USB interface structure.
* @id: Pointer to the usb_device_id structure. * @id: Pointer to the usb_device_id structure.
* *
* Return: 0 on success, -1 on failure. * Return: 0 on success, a negative error code on failure.
*/ */
static int rsi_probe(struct usb_interface *pfunction, static int rsi_probe(struct usb_interface *pfunction,
const struct usb_device_id *id) const struct usb_device_id *id)
...@@ -445,6 +457,7 @@ static int rsi_probe(struct usb_interface *pfunction, ...@@ -445,6 +457,7 @@ static int rsi_probe(struct usb_interface *pfunction,
struct rsi_hw *adapter; struct rsi_hw *adapter;
struct rsi_91x_usbdev *dev; struct rsi_91x_usbdev *dev;
u16 fw_status; u16 fw_status;
int status;
rsi_dbg(INIT_ZONE, "%s: Init function called\n", __func__); rsi_dbg(INIT_ZONE, "%s: Init function called\n", __func__);
...@@ -452,10 +465,11 @@ static int rsi_probe(struct usb_interface *pfunction, ...@@ -452,10 +465,11 @@ static int rsi_probe(struct usb_interface *pfunction,
if (!adapter) { if (!adapter) {
rsi_dbg(ERR_ZONE, "%s: Failed to init os intf ops\n", rsi_dbg(ERR_ZONE, "%s: Failed to init os intf ops\n",
__func__); __func__);
return 1; return -ENOMEM;
} }
if (rsi_init_usb_interface(adapter, pfunction)) { status = rsi_init_usb_interface(adapter, pfunction);
if (status) {
rsi_dbg(ERR_ZONE, "%s: Failed to init usb interface\n", rsi_dbg(ERR_ZONE, "%s: Failed to init usb interface\n",
__func__); __func__);
goto err; goto err;
...@@ -465,26 +479,30 @@ static int rsi_probe(struct usb_interface *pfunction, ...@@ -465,26 +479,30 @@ static int rsi_probe(struct usb_interface *pfunction,
dev = (struct rsi_91x_usbdev *)adapter->rsi_dev; dev = (struct rsi_91x_usbdev *)adapter->rsi_dev;
if (rsi_usb_reg_read(dev->usbdev, FW_STATUS_REG, &fw_status, 2) < 0) status = rsi_usb_reg_read(dev->usbdev, FW_STATUS_REG, &fw_status, 2);
if (status)
goto err1; goto err1;
else else
fw_status &= 1; fw_status &= 1;
if (!fw_status) { if (!fw_status) {
if (rsi_usb_device_init(adapter->priv)) { status = rsi_usb_device_init(adapter->priv);
if (status) {
rsi_dbg(ERR_ZONE, "%s: Failed in device init\n", rsi_dbg(ERR_ZONE, "%s: Failed in device init\n",
__func__); __func__);
goto err1; goto err1;
} }
if (rsi_usb_reg_write(dev->usbdev, status = rsi_usb_reg_write(dev->usbdev,
USB_INTERNAL_REG_1, USB_INTERNAL_REG_1,
RSI_USB_READY_MAGIC_NUM, 1) < 0) RSI_USB_READY_MAGIC_NUM, 1);
if (status)
goto err1; goto err1;
rsi_dbg(INIT_ZONE, "%s: Performed device init\n", __func__); rsi_dbg(INIT_ZONE, "%s: Performed device init\n", __func__);
} }
if (rsi_rx_urb_submit(adapter)) status = rsi_rx_urb_submit(adapter);
if (status)
goto err1; goto err1;
return 0; return 0;
...@@ -493,7 +511,7 @@ static int rsi_probe(struct usb_interface *pfunction, ...@@ -493,7 +511,7 @@ static int rsi_probe(struct usb_interface *pfunction,
err: err:
rsi_91x_deinit(adapter); rsi_91x_deinit(adapter);
rsi_dbg(ERR_ZONE, "%s: Failed in probe...Exiting\n", __func__); rsi_dbg(ERR_ZONE, "%s: Failed in probe...Exiting\n", __func__);
return 1; return status;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment