Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] rtl28xxu: fix control message flaws

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>

authored by

Antti Palosaari and committed by
Mauro Carvalho Chehab
d18ca5b7 17f38822

+14 -3
+13 -2
drivers/media/usb/dvb-usb-v2/rtl28xxu.c
··· 34 34 unsigned int pipe; 35 35 u8 requesttype; 36 36 37 + mutex_lock(&d->usb_mutex); 38 + 39 + if (req->size > sizeof(dev->buf)) { 40 + dev_err(&d->intf->dev, "too large message %u\n", req->size); 41 + ret = -EINVAL; 42 + goto err_mutex_unlock; 43 + } 44 + 37 45 if (req->index & CMD_WR_FLAG) { 38 46 /* write */ 39 47 memcpy(dev->buf, req->data, req->size); ··· 58 50 dvb_usb_dbg_usb_control_msg(d->udev, 0, requesttype, req->value, 59 51 req->index, dev->buf, req->size); 60 52 if (ret < 0) 61 - goto err; 53 + goto err_mutex_unlock; 62 54 63 55 /* read request, copy returned data to return buf */ 64 56 if (requesttype == (USB_TYPE_VENDOR | USB_DIR_IN)) 65 57 memcpy(req->data, dev->buf, req->size); 66 58 59 + mutex_unlock(&d->usb_mutex); 60 + 67 61 return 0; 68 - err: 62 + err_mutex_unlock: 63 + mutex_unlock(&d->usb_mutex); 69 64 dev_dbg(&d->intf->dev, "failed=%d\n", ret); 70 65 return ret; 71 66 }
+1 -1
drivers/media/usb/dvb-usb-v2/rtl28xxu.h
··· 71 71 72 72 73 73 struct rtl28xxu_dev { 74 - u8 buf[28]; 74 + u8 buf[128]; 75 75 u8 chip_id; 76 76 u8 tuner; 77 77 char *tuner_name;