From: Shuah Khan skhan@linuxfoundation.org
commit 3776c78559853fd151be7c41e369fd076fb679d5 upstream.
rtsx_usb uses same buffer for command and response. There could be a potential conflict using the same buffer for both especially if retries and timeouts are involved.
Use separate command and response buffers to avoid conflicts.
Signed-off-by: Shuah Khan skhan@linuxfoundation.org Cc: stable stable@kernel.org Link: https://lore.kernel.org/r/07e3721804ff07aaab9ef5b39a5691d0718b9ade.165664216... Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/misc/cardreader/rtsx_usb.c | 26 +++++++++++++++++--------- include/linux/rtsx_usb.h | 1 - 2 files changed, 17 insertions(+), 10 deletions(-)
--- a/drivers/misc/cardreader/rtsx_usb.c +++ b/drivers/misc/cardreader/rtsx_usb.c @@ -642,15 +642,18 @@ static int rtsx_usb_probe(struct usb_int
ucr->pusb_dev = usb_dev;
- ucr->iobuf = kmalloc(IOBUF_SIZE, GFP_KERNEL); - if (!ucr->iobuf) + ucr->cmd_buf = kmalloc(IOBUF_SIZE, GFP_KERNEL); + if (!ucr->cmd_buf) return -ENOMEM;
+ ucr->rsp_buf = kmalloc(IOBUF_SIZE, GFP_KERNEL); + if (!ucr->rsp_buf) + goto out_free_cmd_buf; + usb_set_intfdata(intf, ucr);
ucr->vendor_id = id->idVendor; ucr->product_id = id->idProduct; - ucr->cmd_buf = ucr->rsp_buf = ucr->iobuf;
mutex_init(&ucr->dev_mutex);
@@ -678,9 +681,11 @@ static int rtsx_usb_probe(struct usb_int
out_init_fail: usb_set_intfdata(ucr->pusb_intf, NULL); - kfree(ucr->iobuf); - ucr->iobuf = NULL; - ucr->cmd_buf = ucr->rsp_buf = NULL; + kfree(ucr->rsp_buf); + ucr->rsp_buf = NULL; +out_free_cmd_buf: + kfree(ucr->cmd_buf); + ucr->cmd_buf = NULL; return ret; }
@@ -693,9 +698,12 @@ static void rtsx_usb_disconnect(struct u mfd_remove_devices(&intf->dev);
usb_set_intfdata(ucr->pusb_intf, NULL); - kfree(ucr->iobuf); - ucr->iobuf = NULL; - ucr->cmd_buf = ucr->rsp_buf = NULL; + + kfree(ucr->cmd_buf); + ucr->cmd_buf = NULL; + + kfree(ucr->rsp_buf); + ucr->rsp_buf = NULL; }
#ifdef CONFIG_PM --- a/include/linux/rtsx_usb.h +++ b/include/linux/rtsx_usb.h @@ -65,7 +65,6 @@ struct rtsx_ucr { struct usb_device *pusb_dev; struct usb_interface *pusb_intf; struct usb_sg_request current_sg; - unsigned char *iobuf;
struct timer_list sg_timer; struct mutex dev_mutex;