From: Jeongjun Park <aha310510@gmail.com>
To: mchehab@kernel.org, hverkuil@xs4all.nl, hverkuil+cisco@kernel.org
Cc: linux-media@vger.kernel.org, linux-kernel@vger.kernel.org,
stable@vger.kernel.org, aha310510@gmail.com,
syzbot+0192952caa411a3be209@syzkaller.appspotmail.com
Subject: [PATCH v2 1/2] media: az6007: fix out-of-bounds in az6007_i2c_xfer()
Date: Tue, 9 Sep 2025 00:07:29 +0900 [thread overview]
Message-ID: <20250908150730.24560-2-aha310510@gmail.com> (raw)
In-Reply-To: <20250908150730.24560-1-aha310510@gmail.com>
Because the blen is not properly bounds-checked in __az6007_read/write,
it is easy to get out-of-bounds errors in az6007_i2c_xfer later.
Therefore, we need to add bounds-checking to __az6007_read/write to
resolve this.
Cc: <stable@vger.kernel.org>
Reported-by: syzbot+0192952caa411a3be209@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=0192952caa411a3be209
Fixes: 786baecfe78f ("[media] dvb-usb: move it to drivers/media/usb/dvb-usb")
Signed-off-by: Jeongjun Park <aha310510@gmail.com>
---
v2: Change to fix the root cause of oob
- Link to v1: https://lore.kernel.org/all/20250421105555.34984-1-aha310510@gmail.com/
---
drivers/media/usb/dvb-usb-v2/az6007.c | 62 +++++++++++++++------------
1 file changed, 34 insertions(+), 28 deletions(-)
diff --git a/drivers/media/usb/dvb-usb-v2/az6007.c b/drivers/media/usb/dvb-usb-v2/az6007.c
index 65ef045b74ca..4202042bdb55 100644
--- a/drivers/media/usb/dvb-usb-v2/az6007.c
+++ b/drivers/media/usb/dvb-usb-v2/az6007.c
@@ -97,11 +97,17 @@ static struct mt2063_config az6007_mt2063_config = {
.refclock = 36125000,
};
-static int __az6007_read(struct usb_device *udev, u8 req, u16 value,
- u16 index, u8 *b, int blen)
+static int __az6007_read(struct usb_device *udev, struct az6007_device_state *st,
+ u8 req, u16 value, u16 index, u8 *b, int blen)
{
int ret;
+ if (blen > sizeof(st->data)) {
+ pr_err("az6007: tried to read %d bytes, but I2C max size is %lu bytes\n",
+ blen, sizeof(st->data));
+ return -EOPNOTSUPP;
+ }
+
ret = usb_control_msg(udev,
usb_rcvctrlpipe(udev, 0),
req,
@@ -125,24 +131,30 @@ static int __az6007_read(struct usb_device *udev, u8 req, u16 value,
static int az6007_read(struct dvb_usb_device *d, u8 req, u16 value,
u16 index, u8 *b, int blen)
{
- struct az6007_device_state *st = d->priv;
+ struct az6007_device_state *st = d_to_priv(d);
int ret;
if (mutex_lock_interruptible(&st->mutex) < 0)
return -EAGAIN;
- ret = __az6007_read(d->udev, req, value, index, b, blen);
+ ret = __az6007_read(d->udev, st, req, value, index, b, blen);
mutex_unlock(&st->mutex);
return ret;
}
-static int __az6007_write(struct usb_device *udev, u8 req, u16 value,
- u16 index, u8 *b, int blen)
+static int __az6007_write(struct usb_device *udev, struct az6007_device_state *st,
+ u8 req, u16 value, u16 index, u8 *b, int blen)
{
int ret;
+ if (blen > sizeof(st->data)) {
+ pr_err("az6007: tried to write %d bytes, but I2C max size is %lu bytes\n",
+ blen, sizeof(st->data));
+ return -EOPNOTSUPP;
+ }
+
if (az6007_xfer_debug) {
printk(KERN_DEBUG "az6007: OUT req: %02x, value: %04x, index: %04x\n",
req, value, index);
@@ -150,12 +162,6 @@ static int __az6007_write(struct usb_device *udev, u8 req, u16 value,
DUMP_PREFIX_NONE, b, blen);
}
- if (blen > 64) {
- pr_err("az6007: tried to write %d bytes, but I2C max size is 64 bytes\n",
- blen);
- return -EOPNOTSUPP;
- }
-
ret = usb_control_msg(udev,
usb_sndctrlpipe(udev, 0),
req,
@@ -172,13 +178,13 @@ static int __az6007_write(struct usb_device *udev, u8 req, u16 value,
static int az6007_write(struct dvb_usb_device *d, u8 req, u16 value,
u16 index, u8 *b, int blen)
{
- struct az6007_device_state *st = d->priv;
+ struct az6007_device_state *st = d_to_priv(d);
int ret;
if (mutex_lock_interruptible(&st->mutex) < 0)
return -EAGAIN;
- ret = __az6007_write(d->udev, req, value, index, b, blen);
+ ret = __az6007_write(d->udev, st, req, value, index, b, blen);
mutex_unlock(&st->mutex);
@@ -775,7 +781,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
value = addr | (1 << 8);
length = 6 + msgs[i + 1].len;
len = msgs[i + 1].len;
- ret = __az6007_read(d->udev, req, value, index,
+ ret = __az6007_read(d->udev, st, req, value, index,
st->data, length);
if (ret >= len) {
for (j = 0; j < len; j++)
@@ -788,7 +794,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
if (az6007_xfer_debug)
printk(KERN_DEBUG "az6007: I2C W addr=0x%x len=%d\n",
addr, msgs[i].len);
- if (msgs[i].len < 1) {
+ if (msgs[i].len < 1 && msgs[i].len > 64) {
ret = -EIO;
goto err;
}
@@ -796,11 +802,8 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
index = msgs[i].buf[0];
value = addr | (1 << 8);
length = msgs[i].len - 1;
- len = msgs[i].len - 1;
- for (j = 0; j < len; j++)
- st->data[j] = msgs[i].buf[j + 1];
- ret = __az6007_write(d->udev, req, value, index,
- st->data, length);
+ ret = __az6007_write(d->udev, st, req, value, index,
+ &msgs[i].buf[1], length);
} else {
/* read bytes */
if (az6007_xfer_debug)
@@ -815,10 +818,12 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
value = addr;
length = msgs[i].len + 6;
len = msgs[i].len;
- ret = __az6007_read(d->udev, req, value, index,
+ ret = __az6007_read(d->udev, st, req, value, index,
st->data, length);
- for (j = 0; j < len; j++)
- msgs[i].buf[j] = st->data[j + 5];
+ if (ret >= len) {
+ for (j = 0; j < len; j++)
+ msgs[i].buf[j] = st->data[j + 5];
+ }
}
if (ret < 0)
goto err;
@@ -845,6 +850,7 @@ static const struct i2c_algorithm az6007_i2c_algo = {
static int az6007_identify_state(struct dvb_usb_device *d, const char **name)
{
+ struct az6007_device_state *state = d_to_priv(d);
int ret;
u8 *mac;
@@ -855,7 +861,7 @@ static int az6007_identify_state(struct dvb_usb_device *d, const char **name)
return -ENOMEM;
/* Try to read the mac address */
- ret = __az6007_read(d->udev, AZ6007_READ_DATA, 6, 0, mac, 6);
+ ret = __az6007_read(d->udev, state, AZ6007_READ_DATA, 6, 0, mac, 6);
if (ret == 6)
ret = WARM;
else
@@ -864,9 +870,9 @@ static int az6007_identify_state(struct dvb_usb_device *d, const char **name)
kfree(mac);
if (ret == COLD) {
- __az6007_write(d->udev, 0x09, 1, 0, NULL, 0);
- __az6007_write(d->udev, 0x00, 0, 0, NULL, 0);
- __az6007_write(d->udev, 0x00, 0, 0, NULL, 0);
+ __az6007_write(d->udev, state, 0x09, 1, 0, NULL, 0);
+ __az6007_write(d->udev, state, 0x00, 0, 0, NULL, 0);
+ __az6007_write(d->udev, state, 0x00, 0, 0, NULL, 0);
}
pr_debug("Device is on %s state\n",
--
next prev parent reply other threads:[~2025-09-08 15:07 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-09-08 15:07 [PATCH v2 0/2] media: az6007: overall refactor to fix bugs Jeongjun Park
2025-09-08 15:07 ` Jeongjun Park [this message]
2025-09-09 5:55 ` [PATCH v2 1/2] media: az6007: fix out-of-bounds in az6007_i2c_xfer() kernel test robot
2025-10-14 11:03 ` hverkuil+cisco
2025-09-08 15:07 ` [PATCH v2 2/2] media: az6007: refactor to properly use dvb-usb-v2 Jeongjun Park
2025-10-14 11:45 ` hverkuil+cisco
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250908150730.24560-2-aha310510@gmail.com \
--to=aha310510@gmail.com \
--cc=hverkuil+cisco@kernel.org \
--cc=hverkuil@xs4all.nl \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=mchehab@kernel.org \
--cc=stable@vger.kernel.org \
--cc=syzbot+0192952caa411a3be209@syzkaller.appspotmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.