[PATCH] media: lmedm04: bound I2C transfer buffers
From: Pengpeng Hou
Date: Fri Jul 03 2026 - 21:15:33 EST
lme2510_i2c_xfer() stages I2C transfers in fixed 64-byte obuf and
ibuf arrays. It copies caller-provided write bytes into obuf and
copies read replies from ibuf without checking that the requested I2C
message lengths fit those staging buffers.
Reject write and read lengths that exceed the local USB command and
reply buffers before copying to or from them.
Signed-off-by: Pengpeng Hou <pengpeng@xxxxxxxxxxx>
---
drivers/media/usb/dvb-usb-v2/lmedm04.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
--- a/drivers/media/usb/dvb-usb-v2/lmedm04.c
+++ b/drivers/media/usb/dvb-usb-v2/lmedm04.c
@@ -499,6 +499,7 @@
struct lme2510_state *st = d->priv;
static u8 obuf[64], ibuf[64];
int i, read, read_o;
+ int ret = -EINVAL;
u16 len;
u8 gate;
@@ -522,22 +523,29 @@
obuf[2] = msg[i].addr << 1;
if (read) {
- if (read_o)
+ if (read_o) {
+ if (msg[i].len > sizeof(ibuf) - 1)
+ goto unlock;
len = 3;
- else {
+ } else {
+ if (msg[i].len > sizeof(obuf) - 4 ||
+ msg[i + 1].len > sizeof(ibuf) - 1)
+ goto unlock;
memcpy(&obuf[3], msg[i].buf, msg[i].len);
obuf[msg[i].len+3] = msg[i+1].len;
len = msg[i].len+4;
}
} else {
+ if (msg[i].len > sizeof(obuf) - 3)
+ goto unlock;
memcpy(&obuf[3], msg[i].buf, msg[i].len);
len = msg[i].len+3;
}
if (lme2510_msg(d, obuf, len, ibuf, 64) < 0) {
deb_info(1, "i2c transfer failed.");
- mutex_unlock(&d->i2c_mutex);
- return -EAGAIN;
+ ret = -EAGAIN;
+ goto unlock;
}
if (read) {
@@ -550,8 +558,11 @@
}
}
+ ret = i;
+
+unlock:
mutex_unlock(&d->i2c_mutex);
- return i;
+ return ret;
}
static u32 lme2510_i2c_func(struct i2c_adapter *adapter)