diff mbox series

media: dvb-usb: az6027: fix return value of az6027_i2c_xfer()

Message ID f4dd058f-7854-4a93-b0c7-608e850bb548@magd.ox.ac.uk
State New
Headers show
Series media: dvb-usb: az6027: fix return value of az6027_i2c_xfer() | expand

Commit Message

Praveen Balakrishnan May 5, 2025, 9:20 p.m. UTC
syzbot found an infoleak bug triggered by the az6027 driver [1].

In az6027_i2c_xfer, the return value counts the number of messages
passed to it, when it should count actually executed messages. As a
result, i2cdev_ioctl_smbus can copy an unwritten buffer to the user.

Introduce a separate return value counter that only counts executed
messages.

[1] https://syzkaller.appspot.com/bug?extid=08b819a87faa6def6dfb

Closes: https://syzkaller.appspot.com/bug?extid=08b819a87faa6def6dfb
Tested-by: syzbot+08b819a87faa6def6dfb@syzkaller.appspotmail.com
Reported-by: syzbot+08b819a87faa6def6dfb@syzkaller.appspotmail.com
Signed-off-by: Praveen Balakrishnan <praveen.balakrishnan@magd.ox.ac.uk>
---
 drivers/media/usb/dvb-usb/az6027.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/drivers/media/usb/dvb-usb/az6027.c b/drivers/media/usb/dvb-usb/az6027.c
index 056935d3cbd6..be9cbbd4723d 100644
--- a/drivers/media/usb/dvb-usb/az6027.c
+++ b/drivers/media/usb/dvb-usb/az6027.c
@@ -957,6 +957,7 @@  static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n
 	int length;
 	u8 req;
 	u8 *data;
+	int ret = 0;
 
 	data = kmalloc(256, GFP_KERNEL);
 	if (!data)
@@ -976,12 +977,13 @@  static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n
 			req = 0xBE;
 			index = 0;
 			if (msg[i].len < 1) {
-				i = -EOPNOTSUPP;
+				ret = -EOPNOTSUPP;
 				break;
 			}
 			value = msg[i].buf[0] & 0x00ff;
 			length = 1;
 			az6027_usb_out_op(d, req, value, index, data, length);
+			ret++;
 		}
 
 		if (msg[i].addr == 0xd0) {
@@ -1001,12 +1003,13 @@  static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n
 					msg[i + 1].buf[j] = data[j + 5];
 
 				i++;
+				ret++;
 			} else {
 
 				/* demod 16bit addr */
 				req = 0xBD;
 				if (msg[i].len < 1) {
-					i = -EOPNOTSUPP;
+					ret = -EOPNOTSUPP;
 					break;
 				}
 				index = (((msg[i].buf[0] << 8) & 0xff00) | (msg[i].buf[1] & 0x00ff));
@@ -1017,6 +1020,7 @@  static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n
 					data[j] = msg[i].buf[j + 2];
 				az6027_usb_out_op(d, req, value, index, data, length);
 			}
+			ret++;
 		}
 
 		if (msg[i].addr == 0xc0) {
@@ -1035,7 +1039,7 @@  static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n
 
 				req = 0xBD;
 				if (msg[i].len < 1) {
-					i = -EOPNOTSUPP;
+					ret = -EOPNOTSUPP;
 					break;
 				}
 				index = msg[i].buf[0] & 0x00FF;
@@ -1048,12 +1052,13 @@  static int az6027_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int n
 
 				az6027_usb_out_op(d, req, value, index, data, length);
 			}
+			ret++;
 		}
 	}
 	mutex_unlock(&d->i2c_mutex);
 	kfree(data);
 
-	return i;
+	return ret;
 }