[media] rtl28xxu: fix control message flaws
authorAntti Palosaari <crope@iki.fi>
Tue, 6 Oct 2015 03:22:23 +0000 (00:22 -0300)
committerMauro Carvalho Chehab <mchehab@osg.samsung.com>
Thu, 22 Oct 2015 17:48:27 +0000 (15:48 -0200)
Add lock to prevent concurrent access for control message as control
message function uses shared buffer. Without the lock there may be
remote control polling which messes the buffer causing IO errors.
Increase buffer size and add check for maximum supported message
length.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=103391
Fixes: c56222a6b25c ("[media] rtl28xxu: move usb buffers to state")

Cc: <stable@vger.kernel.org> # 4.0+
Signed-off-by: Antti Palosaari <crope@iki.fi>
drivers/media/usb/dvb-usb-v2/rtl28xxu.c
drivers/media/usb/dvb-usb-v2/rtl28xxu.h

index c3cac4c12fb3c6c18315ab83941a3454dc5ce9bd..197a4f2e54d2a1c08a3c662b3f983b57bf8190dd 100644 (file)
@@ -34,6 +34,14 @@ static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
        unsigned int pipe;
        u8 requesttype;
 
+       mutex_lock(&d->usb_mutex);
+
+       if (req->size > sizeof(dev->buf)) {
+               dev_err(&d->intf->dev, "too large message %u\n", req->size);
+               ret = -EINVAL;
+               goto err_mutex_unlock;
+       }
+
        if (req->index & CMD_WR_FLAG) {
                /* write */
                memcpy(dev->buf, req->data, req->size);
@@ -50,14 +58,17 @@ static int rtl28xxu_ctrl_msg(struct dvb_usb_device *d, struct rtl28xxu_req *req)
        dvb_usb_dbg_usb_control_msg(d->udev, 0, requesttype, req->value,
                        req->index, dev->buf, req->size);
        if (ret < 0)
-               goto err;
+               goto err_mutex_unlock;
 
        /* read request, copy returned data to return buf */
        if (requesttype == (USB_TYPE_VENDOR | USB_DIR_IN))
                memcpy(req->data, dev->buf, req->size);
 
+       mutex_unlock(&d->usb_mutex);
+
        return 0;
-err:
+err_mutex_unlock:
+       mutex_unlock(&d->usb_mutex);
        dev_dbg(&d->intf->dev, "failed=%d\n", ret);
        return ret;
 }
index 9f6115a2ee0166d509584d5b5c5fd0b62d5bff06..138062960a7367737521659acc607983c921a685 100644 (file)
@@ -71,7 +71,7 @@
 
 
 struct rtl28xxu_dev {
-       u8 buf[28];
+       u8 buf[128];
        u8 chip_id;
        u8 tuner;
        char *tuner_name;