media: m920x: don't use stack on USB reads
authorMauro Carvalho Chehab <mchehab+huawei@kernel.org>
Mon, 6 Dec 2021 14:34:19 +0000 (15:34 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 27 Jan 2022 10:04:36 +0000 (11:04 +0100)
[ Upstream commit a2ab06d7c4d6bfd0b545a768247a70463e977e27 ]

Using stack-allocated pointers for USB message data don't work.
This driver is almost OK with that, except for the I2C read
logic.

Fix it by using a temporary read buffer, just like on all other
calls to m920x_read().

Link: https://lore.kernel.org/all/ccc99e48-de4f-045e-0fe4-61e3118e3f74@mida.se/
Reported-by: rkardell@mida.se
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
drivers/media/usb/dvb-usb/m920x.c

index 4bb5b82..691e058 100644 (file)
@@ -274,6 +274,13 @@ static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int nu
                        /* Should check for ack here, if we knew how. */
                }
                if (msg[i].flags & I2C_M_RD) {
+                       char *read = kmalloc(1, GFP_KERNEL);
+                       if (!read) {
+                               ret = -ENOMEM;
+                               kfree(read);
+                               goto unlock;
+                       }
+
                        for (j = 0; j < msg[i].len; j++) {
                                /* Last byte of transaction?
                                 * Send STOP, otherwise send ACK. */
@@ -281,9 +288,12 @@ static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int nu
 
                                if ((ret = m920x_read(d->udev, M9206_I2C, 0x0,
                                                      0x20 | stop,
-                                                     &msg[i].buf[j], 1)) != 0)
+                                                     read, 1)) != 0)
                                        goto unlock;
+                               msg[i].buf[j] = read[0];
                        }
+
+                       kfree(read);
                } else {
                        for (j = 0; j < msg[i].len; j++) {
                                /* Last byte of transaction? Then send STOP. */