media: mceusb: do not read data parameters unless required
This causes out-of-bounds read on device probe. BUG: KASAN: slab-out-of-bounds in mceusb_dev_printdata+0xdc/0x830 [mceusb] Signed-off-by: Sean Young <sean@mess.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>
This commit is contained in:
parent
89d8a2cc51
commit
ff05cf0937
|
@ -538,12 +538,12 @@ static int mceusb_cmd_datasize(u8 cmd, u8 subcmd)
|
||||||
return datasize;
|
return datasize;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
|
static void mceusb_dev_printdata(struct mceusb_dev *ir, u8 *buf, int buf_len,
|
||||||
int buf_len, int offset, int len, bool out)
|
int offset, int len, bool out)
|
||||||
{
|
{
|
||||||
#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
|
#if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG)
|
||||||
char *inout;
|
char *inout;
|
||||||
u8 cmd, subcmd, data1, data2, data3, data4;
|
u8 cmd, subcmd, *data;
|
||||||
struct device *dev = ir->dev;
|
struct device *dev = ir->dev;
|
||||||
int start, skip = 0;
|
int start, skip = 0;
|
||||||
u32 carrier, period;
|
u32 carrier, period;
|
||||||
|
@ -564,17 +564,14 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
|
||||||
start = offset + skip;
|
start = offset + skip;
|
||||||
cmd = buf[start] & 0xff;
|
cmd = buf[start] & 0xff;
|
||||||
subcmd = buf[start + 1] & 0xff;
|
subcmd = buf[start + 1] & 0xff;
|
||||||
data1 = buf[start + 2] & 0xff;
|
data = buf + start + 2;
|
||||||
data2 = buf[start + 3] & 0xff;
|
|
||||||
data3 = buf[start + 4] & 0xff;
|
|
||||||
data4 = buf[start + 5] & 0xff;
|
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case MCE_CMD_NULL:
|
case MCE_CMD_NULL:
|
||||||
if (subcmd == MCE_CMD_NULL)
|
if (subcmd == MCE_CMD_NULL)
|
||||||
break;
|
break;
|
||||||
if ((subcmd == MCE_CMD_PORT_SYS) &&
|
if ((subcmd == MCE_CMD_PORT_SYS) &&
|
||||||
(data1 == MCE_CMD_RESUME))
|
(data[0] == MCE_CMD_RESUME))
|
||||||
dev_dbg(dev, "Device resume requested");
|
dev_dbg(dev, "Device resume requested");
|
||||||
else
|
else
|
||||||
dev_dbg(dev, "Unknown command 0x%02x 0x%02x",
|
dev_dbg(dev, "Unknown command 0x%02x 0x%02x",
|
||||||
|
@ -585,7 +582,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
|
||||||
case MCE_RSP_EQEMVER:
|
case MCE_RSP_EQEMVER:
|
||||||
if (!out)
|
if (!out)
|
||||||
dev_dbg(dev, "Emulator interface version %x",
|
dev_dbg(dev, "Emulator interface version %x",
|
||||||
data1);
|
data[0]);
|
||||||
break;
|
break;
|
||||||
case MCE_CMD_G_REVISION:
|
case MCE_CMD_G_REVISION:
|
||||||
if (len == 2)
|
if (len == 2)
|
||||||
|
@ -603,13 +600,13 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
|
||||||
case MCE_RSP_EQWAKEVERSION:
|
case MCE_RSP_EQWAKEVERSION:
|
||||||
if (!out)
|
if (!out)
|
||||||
dev_dbg(dev, "Wake version, proto: 0x%02x, payload: 0x%02x, address: 0x%02x, version: 0x%02x",
|
dev_dbg(dev, "Wake version, proto: 0x%02x, payload: 0x%02x, address: 0x%02x, version: 0x%02x",
|
||||||
data1, data2, data3, data4);
|
data[0], data[1], data[2], data[3]);
|
||||||
break;
|
break;
|
||||||
case MCE_RSP_GETPORTSTATUS:
|
case MCE_RSP_GETPORTSTATUS:
|
||||||
if (!out)
|
if (!out)
|
||||||
/* We use data1 + 1 here, to match hw labels */
|
/* We use data1 + 1 here, to match hw labels */
|
||||||
dev_dbg(dev, "TX port %d: blaster is%s connected",
|
dev_dbg(dev, "TX port %d: blaster is%s connected",
|
||||||
data1 + 1, data4 ? " not" : "");
|
data[0] + 1, data[3] ? " not" : "");
|
||||||
break;
|
break;
|
||||||
case MCE_CMD_FLASHLED:
|
case MCE_CMD_FLASHLED:
|
||||||
dev_dbg(dev, "Attempting to flash LED");
|
dev_dbg(dev, "Attempting to flash LED");
|
||||||
|
@ -630,11 +627,11 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
|
||||||
break;
|
break;
|
||||||
case MCE_CMD_UNKNOWN:
|
case MCE_CMD_UNKNOWN:
|
||||||
dev_dbg(dev, "Resp to 9f 05 of 0x%02x 0x%02x",
|
dev_dbg(dev, "Resp to 9f 05 of 0x%02x 0x%02x",
|
||||||
data1, data2);
|
data[0], data[1]);
|
||||||
break;
|
break;
|
||||||
case MCE_RSP_EQIRCFS:
|
case MCE_RSP_EQIRCFS:
|
||||||
period = DIV_ROUND_CLOSEST(
|
period = DIV_ROUND_CLOSEST((1U << data[0] * 2) *
|
||||||
(1U << data1 * 2) * (data2 + 1), 10);
|
(data[1] + 1), 10);
|
||||||
if (!period)
|
if (!period)
|
||||||
break;
|
break;
|
||||||
carrier = (1000 * 1000) / period;
|
carrier = (1000 * 1000) / period;
|
||||||
|
@ -646,11 +643,12 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
|
||||||
break;
|
break;
|
||||||
case MCE_RSP_EQIRTXPORTS:
|
case MCE_RSP_EQIRTXPORTS:
|
||||||
dev_dbg(dev, "%s transmit blaster mask of 0x%02x",
|
dev_dbg(dev, "%s transmit blaster mask of 0x%02x",
|
||||||
inout, data1);
|
inout, data[0]);
|
||||||
break;
|
break;
|
||||||
case MCE_RSP_EQIRTIMEOUT:
|
case MCE_RSP_EQIRTIMEOUT:
|
||||||
/* value is in units of 50us, so x*50/1000 ms */
|
/* value is in units of 50us, so x*50/1000 ms */
|
||||||
period = ((data1 << 8) | data2) * MCE_TIME_UNIT / 1000;
|
period = ((data[0] << 8) | data[1]) *
|
||||||
|
MCE_TIME_UNIT / 1000;
|
||||||
dev_dbg(dev, "%s receive timeout of %d ms",
|
dev_dbg(dev, "%s receive timeout of %d ms",
|
||||||
inout, period);
|
inout, period);
|
||||||
break;
|
break;
|
||||||
|
@ -662,7 +660,7 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
|
||||||
break;
|
break;
|
||||||
case MCE_RSP_EQIRRXPORTEN:
|
case MCE_RSP_EQIRRXPORTEN:
|
||||||
dev_dbg(dev, "%s %s-range receive sensor in use",
|
dev_dbg(dev, "%s %s-range receive sensor in use",
|
||||||
inout, data1 == 0x02 ? "short" : "long");
|
inout, data[0] == 0x02 ? "short" : "long");
|
||||||
break;
|
break;
|
||||||
case MCE_CMD_GETIRRXPORTEN:
|
case MCE_CMD_GETIRRXPORTEN:
|
||||||
/* aka MCE_RSP_EQIRRXCFCNT */
|
/* aka MCE_RSP_EQIRRXCFCNT */
|
||||||
|
@ -670,13 +668,13 @@ static void mceusb_dev_printdata(struct mceusb_dev *ir, char *buf,
|
||||||
dev_dbg(dev, "Get receive sensor");
|
dev_dbg(dev, "Get receive sensor");
|
||||||
else if (ir->learning_enabled)
|
else if (ir->learning_enabled)
|
||||||
dev_dbg(dev, "RX pulse count: %d",
|
dev_dbg(dev, "RX pulse count: %d",
|
||||||
((data1 << 8) | data2));
|
((data[0] << 8) | data[1]));
|
||||||
break;
|
break;
|
||||||
case MCE_RSP_EQIRNUMPORTS:
|
case MCE_RSP_EQIRNUMPORTS:
|
||||||
if (out)
|
if (out)
|
||||||
break;
|
break;
|
||||||
dev_dbg(dev, "Num TX ports: %x, num RX ports: %x",
|
dev_dbg(dev, "Num TX ports: %x, num RX ports: %x",
|
||||||
data1, data2);
|
data[0], data[1]);
|
||||||
break;
|
break;
|
||||||
case MCE_RSP_CMD_ILLEGAL:
|
case MCE_RSP_CMD_ILLEGAL:
|
||||||
dev_dbg(dev, "Illegal PORT_IR command");
|
dev_dbg(dev, "Illegal PORT_IR command");
|
||||||
|
|
Loading…
Reference in New Issue