| From 44ac8f7e3be02be92892f2555a268fe588c84b1d Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 16 Aug 2019 03:38:13 -0300 |
| Subject: media: gspca: zero usb_buf on error |
| |
| From: Hans Verkuil <hverkuil-cisco@xs4all.nl> |
| |
| [ 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: syzbot+1a35278dd0ebfb3a038a@syzkaller.appspotmail.com |
| Reported-and-tested-by: syzbot+397fd082ce5143e2f67d@syzkaller.appspotmail.com |
| Reported-and-tested-by: syzbot+06ddf1788cfd048c5e82@syzkaller.appspotmail.com |
| |
| Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> |
| Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/media/usb/gspca/konica.c | 5 +++++ |
| drivers/media/usb/gspca/nw80x.c | 5 +++++ |
| drivers/media/usb/gspca/ov519.c | 10 ++++++++++ |
| drivers/media/usb/gspca/ov534.c | 5 +++++ |
| drivers/media/usb/gspca/ov534_9.c | 1 + |
| drivers/media/usb/gspca/se401.c | 5 +++++ |
| drivers/media/usb/gspca/sn9c20x.c | 5 +++++ |
| drivers/media/usb/gspca/sonixb.c | 5 +++++ |
| drivers/media/usb/gspca/sonixj.c | 5 +++++ |
| drivers/media/usb/gspca/spca1528.c | 5 +++++ |
| drivers/media/usb/gspca/sq930x.c | 5 +++++ |
| drivers/media/usb/gspca/sunplus.c | 5 +++++ |
| drivers/media/usb/gspca/vc032x.c | 5 +++++ |
| drivers/media/usb/gspca/w996Xcf.c | 5 +++++ |
| 14 files changed, 71 insertions(+) |
| |
| diff --git a/drivers/media/usb/gspca/konica.c b/drivers/media/usb/gspca/konica.c |
| index 78542fff403fc..5a37d32e8fd09 100644 |
| --- a/drivers/media/usb/gspca/konica.c |
| +++ b/drivers/media/usb/gspca/konica.c |
| @@ -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); |
| } |
| } |
| |
| diff --git a/drivers/media/usb/gspca/nw80x.c b/drivers/media/usb/gspca/nw80x.c |
| index 599f755e75b86..7ebeee98dc1bb 100644 |
| --- a/drivers/media/usb/gspca/nw80x.c |
| +++ b/drivers/media/usb/gspca/nw80x.c |
| @@ -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) |
| diff --git a/drivers/media/usb/gspca/ov519.c b/drivers/media/usb/gspca/ov519.c |
| index 965372a5ff2f3..7ac38905080ad 100644 |
| --- a/drivers/media/usb/gspca/ov519.c |
| +++ b/drivers/media/usb/gspca/ov519.c |
| @@ -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; |
| diff --git a/drivers/media/usb/gspca/ov534.c b/drivers/media/usb/gspca/ov534.c |
| index 9266a5c9abc5d..ba289b4530772 100644 |
| --- a/drivers/media/usb/gspca/ov534.c |
| +++ b/drivers/media/usb/gspca/ov534.c |
| @@ -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]; |
| } |
| diff --git a/drivers/media/usb/gspca/ov534_9.c b/drivers/media/usb/gspca/ov534_9.c |
| index 47085cf2d7236..f2dca06069355 100644 |
| --- a/drivers/media/usb/gspca/ov534_9.c |
| +++ b/drivers/media/usb/gspca/ov534_9.c |
| @@ -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]; |
| } |
| diff --git a/drivers/media/usb/gspca/se401.c b/drivers/media/usb/gspca/se401.c |
| index 5102cea504710..6adbb0eca71fe 100644 |
| --- a/drivers/media/usb/gspca/se401.c |
| +++ b/drivers/media/usb/gspca/se401.c |
| @@ -115,6 +115,11 @@ static void se401_read_req(struct gspca_dev *gspca_dev, u16 req, int silent) |
| pr_err("read req failed req %#04x error %d\n", |
| req, err); |
| gspca_dev->usb_err = err; |
| + /* |
| + * Make sure the buffer is zeroed to avoid uninitialized |
| + * values. |
| + */ |
| + memset(gspca_dev->usb_buf, 0, READ_REQ_SIZE); |
| } |
| } |
| |
| diff --git a/drivers/media/usb/gspca/sn9c20x.c b/drivers/media/usb/gspca/sn9c20x.c |
| index 10269dad9d201..1a08a7a20114c 100644 |
| --- a/drivers/media/usb/gspca/sn9c20x.c |
| +++ b/drivers/media/usb/gspca/sn9c20x.c |
| @@ -923,6 +923,11 @@ static void reg_r(struct gspca_dev *gspca_dev, u16 reg, u16 length) |
| if (unlikely(result < 0 || result != length)) { |
| pr_err("Read register %02x failed %d\n", reg, result); |
| gspca_dev->usb_err = result; |
| + /* |
| + * Make sure the buffer is zeroed to avoid uninitialized |
| + * values. |
| + */ |
| + memset(gspca_dev->usb_buf, 0, USB_BUF_SZ); |
| } |
| } |
| |
| diff --git a/drivers/media/usb/gspca/sonixb.c b/drivers/media/usb/gspca/sonixb.c |
| index 6696b2ec34e96..83e98b85ab6a1 100644 |
| --- a/drivers/media/usb/gspca/sonixb.c |
| +++ b/drivers/media/usb/gspca/sonixb.c |
| @@ -466,6 +466,11 @@ static void reg_r(struct gspca_dev *gspca_dev, |
| dev_err(gspca_dev->v4l2_dev.dev, |
| "Error reading register %02x: %d\n", value, res); |
| gspca_dev->usb_err = res; |
| + /* |
| + * Make sure the result is zeroed to avoid uninitialized |
| + * values. |
| + */ |
| + gspca_dev->usb_buf[0] = 0; |
| } |
| } |
| |
| diff --git a/drivers/media/usb/gspca/sonixj.c b/drivers/media/usb/gspca/sonixj.c |
| index d49d76ec14212..9ec63f75b8ea4 100644 |
| --- a/drivers/media/usb/gspca/sonixj.c |
| +++ b/drivers/media/usb/gspca/sonixj.c |
| @@ -1174,6 +1174,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); |
| } |
| } |
| |
| diff --git a/drivers/media/usb/gspca/spca1528.c b/drivers/media/usb/gspca/spca1528.c |
| index f38fd8949609f..ee93bd443df5d 100644 |
| --- a/drivers/media/usb/gspca/spca1528.c |
| +++ b/drivers/media/usb/gspca/spca1528.c |
| @@ -84,6 +84,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); |
| } |
| } |
| |
| diff --git a/drivers/media/usb/gspca/sq930x.c b/drivers/media/usb/gspca/sq930x.c |
| index e274cf19a3ea2..b236e9dcd4685 100644 |
| --- a/drivers/media/usb/gspca/sq930x.c |
| +++ b/drivers/media/usb/gspca/sq930x.c |
| @@ -438,6 +438,11 @@ static void reg_r(struct gspca_dev *gspca_dev, |
| if (ret < 0) { |
| pr_err("reg_r %04x failed %d\n", value, 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); |
| } |
| } |
| |
| diff --git a/drivers/media/usb/gspca/sunplus.c b/drivers/media/usb/gspca/sunplus.c |
| index 46c9f2229a186..cc3e1478c5a09 100644 |
| --- a/drivers/media/usb/gspca/sunplus.c |
| +++ b/drivers/media/usb/gspca/sunplus.c |
| @@ -268,6 +268,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); |
| } |
| } |
| |
| diff --git a/drivers/media/usb/gspca/vc032x.c b/drivers/media/usb/gspca/vc032x.c |
| index b4efb2fb36fa3..5032b9d7d9bb2 100644 |
| --- a/drivers/media/usb/gspca/vc032x.c |
| +++ b/drivers/media/usb/gspca/vc032x.c |
| @@ -2919,6 +2919,11 @@ static void reg_r_i(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); |
| } |
| } |
| static void reg_r(struct gspca_dev *gspca_dev, |
| diff --git a/drivers/media/usb/gspca/w996Xcf.c b/drivers/media/usb/gspca/w996Xcf.c |
| index 896f1b2b91793..948aaae4d47eb 100644 |
| --- a/drivers/media/usb/gspca/w996Xcf.c |
| +++ b/drivers/media/usb/gspca/w996Xcf.c |
| @@ -147,6 +147,11 @@ static int w9968cf_read_sb(struct sd *sd) |
| } else { |
| pr_err("Read SB reg [01] failed\n"); |
| sd->gspca_dev.usb_err = ret; |
| + /* |
| + * Make sure the buffer is zeroed to avoid uninitialized |
| + * values. |
| + */ |
| + memset(sd->gspca_dev.usb_buf, 0, 2); |
| } |
| |
| udelay(W9968CF_I2C_BUS_DELAY); |
| -- |
| 2.20.1 |
| |