diff options
author | Alexey Khoroshilov | 2011-08-29 22:54:21 +0200 |
---|---|---|
committer | Greg Kroah-Hartman | 2011-09-06 20:46:21 +0200 |
commit | 06b3f44a9784c48c64dfedf5f012deb93049a3aa (patch) | |
tree | 5b65d2d866d968b77f1d49936f4947ea7396595a /drivers/staging/lirc | |
parent | staging: lirc: fix mismatch in mutex lock-unlock in imon_probe (diff) | |
download | kernel-qcow2-linux-06b3f44a9784c48c64dfedf5f012deb93049a3aa.tar.gz kernel-qcow2-linux-06b3f44a9784c48c64dfedf5f012deb93049a3aa.tar.xz kernel-qcow2-linux-06b3f44a9784c48c64dfedf5f012deb93049a3aa.zip |
staging: lirc_sasem: fix NULL pointer dereference in sasem_probe
If any memory allocation failed, goto alloc_status_switch
leads to mutex_unlock(&context->ctx_lock) while context is NULL.
The patch moves alloc_status_switch to handle error conditions
in correct way.
Found by Linux Driver Verification project (linuxtesting.org).
Signed-off-by: Alexey Khoroshilov <khoroshilov@ispras.ru>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/staging/lirc')
-rw-r--r-- | drivers/staging/lirc/lirc_sasem.c | 46 |
1 files changed, 23 insertions, 23 deletions
diff --git a/drivers/staging/lirc/lirc_sasem.c b/drivers/staging/lirc/lirc_sasem.c index 7080cdeab5a6..a2d18b0aa048 100644 --- a/drivers/staging/lirc/lirc_sasem.c +++ b/drivers/staging/lirc/lirc_sasem.c @@ -814,29 +814,6 @@ static int sasem_probe(struct usb_interface *interface, printk(KERN_INFO "%s: Registered Sasem driver (minor:%d)\n", __func__, lirc_minor); -alloc_status_switch: - - switch (alloc_status) { - - case 7: - if (vfd_ep_found) - usb_free_urb(tx_urb); - case 6: - usb_free_urb(rx_urb); - case 5: - lirc_buffer_free(rbuf); - case 4: - kfree(rbuf); - case 3: - kfree(driver); - case 2: - kfree(context); - context = NULL; - case 1: - retval = -ENOMEM; - goto unlock; - } - /* Needed while unregistering! */ driver->minor = lirc_minor; @@ -867,6 +844,29 @@ alloc_status_switch: __func__, dev->bus->busnum, dev->devnum); unlock: mutex_unlock(&context->ctx_lock); + +alloc_status_switch: + switch (alloc_status) { + + case 7: + if (vfd_ep_found) + usb_free_urb(tx_urb); + case 6: + usb_free_urb(rx_urb); + case 5: + lirc_buffer_free(rbuf); + case 4: + kfree(rbuf); + case 3: + kfree(driver); + case 2: + kfree(context); + context = NULL; + case 1: + if (retval == 0) + retval = -ENOMEM; + } + exit: return retval; } |