Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b44a551c authored by Hans Verkuil's avatar Hans Verkuil Committed by Greg Kroah-Hartman
Browse files

media: gspca: zero usb_buf on error

[ Upstream commit 4843a543fad3bf8221cf14e5d5f32d15cee89e84 ]

If reg_r() fails, then gspca_dev->usb_buf was left uninitialized,
and some drivers used the contents of that buffer in logic.

This caused several syzbot errors:

https://syzkaller.appspot.com/bug?extid=397fd082ce5143e2f67d
https://syzkaller.appspot.com/bug?extid=1a35278dd0ebfb3a038a
https://syzkaller.appspot.com/bug?extid=06ddf1788cfd048c5e82



I analyzed the gspca drivers and zeroed the buffer where needed.

Reported-and-tested-by: default avatar <syzbot+1a35278dd0ebfb3a038a@syzkaller.appspotmail.com>
Reported-and-tested-by: default avatar <syzbot+397fd082ce5143e2f67d@syzkaller.appspotmail.com>
Reported-and-tested-by: default avatar <syzbot+06ddf1788cfd048c5e82@syzkaller.appspotmail.com>

Signed-off-by: default avatarHans Verkuil <hverkuil-cisco@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab+samsung@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent f61ee509
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -127,6 +127,11 @@ static void reg_r(struct gspca_dev *gspca_dev, u16 value, u16 index)
	if (ret < 0) {
		pr_err("reg_r err %d\n", ret);
		gspca_dev->usb_err = ret;
		/*
		 * Make sure the buffer is zeroed to avoid uninitialized
		 * values.
		 */
		memset(gspca_dev->usb_buf, 0, 2);
	}
}

+5 −0
Original line number Diff line number Diff line
@@ -1584,6 +1584,11 @@ static void reg_r(struct gspca_dev *gspca_dev,
	if (ret < 0) {
		pr_err("reg_r err %d\n", ret);
		gspca_dev->usb_err = ret;
		/*
		 * Make sure the buffer is zeroed to avoid uninitialized
		 * values.
		 */
		memset(gspca_dev->usb_buf, 0, USB_BUF_SZ);
		return;
	}
	if (len == 1)
+10 −0
Original line number Diff line number Diff line
@@ -2087,6 +2087,11 @@ static int reg_r(struct sd *sd, u16 index)
	} else {
		PERR("reg_r %02x failed %d\n", index, ret);
		sd->gspca_dev.usb_err = ret;
		/*
		 * Make sure the result is zeroed to avoid uninitialized
		 * values.
		 */
		gspca_dev->usb_buf[0] = 0;
	}

	return ret;
@@ -2115,6 +2120,11 @@ static int reg_r8(struct sd *sd,
	} else {
		PERR("reg_r8 %02x failed %d\n", index, ret);
		sd->gspca_dev.usb_err = ret;
		/*
		 * Make sure the buffer is zeroed to avoid uninitialized
		 * values.
		 */
		memset(gspca_dev->usb_buf, 0, 8);
	}

	return ret;
+5 −0
Original line number Diff line number Diff line
@@ -645,6 +645,11 @@ static u8 ov534_reg_read(struct gspca_dev *gspca_dev, u16 reg)
	if (ret < 0) {
		pr_err("read failed %d\n", ret);
		gspca_dev->usb_err = ret;
		/*
		 * Make sure the result is zeroed to avoid uninitialized
		 * values.
		 */
		gspca_dev->usb_buf[0] = 0;
	}
	return gspca_dev->usb_buf[0];
}
+1 −0
Original line number Diff line number Diff line
@@ -1157,6 +1157,7 @@ static u8 reg_r(struct gspca_dev *gspca_dev, u16 reg)
	if (ret < 0) {
		pr_err("reg_r err %d\n", ret);
		gspca_dev->usb_err = ret;
		return 0;
	}
	return gspca_dev->usb_buf[0];
}
Loading