media: dvb-usb-v2/gl861: ensure USB message buffers DMA'able
authorAkihiro Tsukada <tskd08@gmail.com>
Sun, 8 Apr 2018 17:21:38 +0000 (13:21 -0400)
committerMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Sat, 5 May 2018 11:15:48 +0000 (07:15 -0400)
i2c message buf might be on stack.

Signed-off-by: Akihiro Tsukada <tskd08@gmail.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org>
drivers/media/usb/dvb-usb-v2/gl861.c

index b1dbb9af380be78593e8bbbb57e48d8ab7fd0737..4817dfd3e659baf3be495022c3650d2e8afd123d 100644 (file)
@@ -20,6 +20,8 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
        u16 value = addr << (8 + 1);
        int wo = (rbuf == NULL || rlen == 0); /* write-only */
        u8 req, type;
+       u8 *buf;
+       int ret;
 
        if (wo) {
                req = GL861_REQ_I2C_WRITE;
@@ -42,11 +44,23 @@ static int gl861_i2c_msg(struct dvb_usb_device *d, u8 addr,
                                KBUILD_MODNAME, wlen);
                return -EINVAL;
        }
-
+       buf = NULL;
+       if (rlen > 0) {
+               buf = kmalloc(rlen, GFP_KERNEL);
+               if (!buf)
+                       return -ENOMEM;
+       }
        usleep_range(1000, 2000); /* avoid I2C errors */
 
-       return usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type,
-                              value, index, rbuf, rlen, 2000);
+       ret = usb_control_msg(d->udev, usb_rcvctrlpipe(d->udev, 0), req, type,
+                             value, index, buf, rlen, 2000);
+       if (rlen > 0) {
+               if (ret > 0)
+                       memcpy(rbuf, buf, rlen);
+               kfree(buf);
+       }
+
+       return ret;
 }
 
 /* I2C */