diff options
author | Christian Lamparter <chunkeey@googlemail.com> | 2010-10-15 19:38:46 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-10-25 14:43:13 -0400 |
commit | cae7f953e8afa9b1ce234fd0907183b643cc5ab8 (patch) | |
tree | b1755091c8b48bcdafda1656f8cc7404bc05bee2 /drivers/net | |
parent | 9192f715bc6304b97fe06c6215d4897a5c279e81 (diff) |
carl9170: fix async command buffer leak
If __carl9170_exec_cmd fails to upload an asynchronous
command to the device, the functions: carl9170_reboot
and carl9170_powersave will leak the temporary command
assembly buffer.
Signed-off-by: Christian Lamparter <chunkeey@googlemail.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/ath/carl9170/usb.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/drivers/net/wireless/ath/carl9170/usb.c b/drivers/net/wireless/ath/carl9170/usb.c index c7f6193934ea..d8607f4c144d 100644 --- a/drivers/net/wireless/ath/carl9170/usb.c +++ b/drivers/net/wireless/ath/carl9170/usb.c | |||
@@ -591,16 +591,23 @@ int __carl9170_exec_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd, | |||
591 | const bool free_buf) | 591 | const bool free_buf) |
592 | { | 592 | { |
593 | struct urb *urb; | 593 | struct urb *urb; |
594 | int err = 0; | ||
594 | 595 | ||
595 | if (!IS_INITIALIZED(ar)) | 596 | if (!IS_INITIALIZED(ar)) { |
596 | return -EPERM; | 597 | err = -EPERM; |
598 | goto err_free; | ||
599 | } | ||
597 | 600 | ||
598 | if (WARN_ON(cmd->hdr.len > CARL9170_MAX_CMD_LEN - 4)) | 601 | if (WARN_ON(cmd->hdr.len > CARL9170_MAX_CMD_LEN - 4)) { |
599 | return -EINVAL; | 602 | err = -EINVAL; |
603 | goto err_free; | ||
604 | } | ||
600 | 605 | ||
601 | urb = usb_alloc_urb(0, GFP_ATOMIC); | 606 | urb = usb_alloc_urb(0, GFP_ATOMIC); |
602 | if (!urb) | 607 | if (!urb) { |
603 | return -ENOMEM; | 608 | err = -ENOMEM; |
609 | goto err_free; | ||
610 | } | ||
604 | 611 | ||
605 | usb_fill_int_urb(urb, ar->udev, usb_sndintpipe(ar->udev, | 612 | usb_fill_int_urb(urb, ar->udev, usb_sndintpipe(ar->udev, |
606 | AR9170_USB_EP_CMD), cmd, cmd->hdr.len + 4, | 613 | AR9170_USB_EP_CMD), cmd, cmd->hdr.len + 4, |
@@ -613,6 +620,12 @@ int __carl9170_exec_cmd(struct ar9170 *ar, struct carl9170_cmd *cmd, | |||
613 | usb_free_urb(urb); | 620 | usb_free_urb(urb); |
614 | 621 | ||
615 | return carl9170_usb_submit_cmd_urb(ar); | 622 | return carl9170_usb_submit_cmd_urb(ar); |
623 | |||
624 | err_free: | ||
625 | if (free_buf) | ||
626 | kfree(cmd); | ||
627 | |||
628 | return err; | ||
616 | } | 629 | } |
617 | 630 | ||
618 | int carl9170_exec_cmd(struct ar9170 *ar, const enum carl9170_cmd_oids cmd, | 631 | int carl9170_exec_cmd(struct ar9170 *ar, const enum carl9170_cmd_oids cmd, |