]> git.itanic.dy.fi Git - linux-stable/commitdiff
media: gspca: zero usb_buf on error
authorHans Verkuil <hverkuil-cisco@xs4all.nl>
Fri, 16 Aug 2019 06:38:13 +0000 (03:38 -0300)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 5 Oct 2019 10:27:47 +0000 (12:27 +0200)
[ 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>
14 files changed:
drivers/media/usb/gspca/konica.c
drivers/media/usb/gspca/nw80x.c
drivers/media/usb/gspca/ov519.c
drivers/media/usb/gspca/ov534.c
drivers/media/usb/gspca/ov534_9.c
drivers/media/usb/gspca/se401.c
drivers/media/usb/gspca/sn9c20x.c
drivers/media/usb/gspca/sonixb.c
drivers/media/usb/gspca/sonixj.c
drivers/media/usb/gspca/spca1528.c
drivers/media/usb/gspca/sq930x.c
drivers/media/usb/gspca/sunplus.c
drivers/media/usb/gspca/vc032x.c
drivers/media/usb/gspca/w996Xcf.c

index 0f6d57fbf91b7878f08ae4c587051ae36dbd4e6a..624b4d24716dd712e03084daf3d5d9a6421dcf83 100644 (file)
@@ -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);
        }
 }
 
index 599f755e75b86513c28228468bc19e15278a414a..7ebeee98dc1bb679db4380cbac02df91a751c0e7 100644 (file)
@@ -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)
index c95f32a0c02b4283d0f4c66b253e0a7e402f392d..c7aafdbb57384bd9b4127a63134060dc58763ce7 100644 (file)
@@ -2116,6 +2116,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;
@@ -2142,6 +2147,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;
index bfff1d1c70ab0149b79bea42752140e292a9fe19..466f984312ddbb6e142d4788f9da1ab8c27c7f03 100644 (file)
@@ -644,6 +644,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];
 }
index 47085cf2d72365b5fdac410d5394bbdb8a7407b0..f2dca06069355c0f55bb243bffb1e6a40dbf836b 100644 (file)
@@ -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];
 }
index 5102cea504710c5c2aeeba1b0101159f35b0b459..6adbb0eca71fe78bb1aeb48b22f7bd0a60f993fa 100644 (file)
@@ -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);
        }
 }
 
index d0ee899584a9f1188d44613ec6f21228a0e94e7a..e5bd1e84fd87598145c82d5c78c56cb76a863b85 100644 (file)
@@ -924,6 +924,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);
        }
 }
 
index 6696b2ec34e969dd631a91ca2dbe6b3ac5fac1fd..83e98b85ab6a1d3f65fe7d44ae91540af065adba 100644 (file)
@@ -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;
        }
 }
 
index fd1c8706d86a8ca03d617ae0c0e94704258a7373..67e23557a1a94d7d46b171280429125d8dc05787 100644 (file)
@@ -1175,6 +1175,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);
        }
 }
 
index f38fd8949609fd917cee8568a4cba9bdb5e83cb4..ee93bd443df5d1411514b79681fd84b0d05dc993 100644 (file)
@@ -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);
        }
 }
 
index e274cf19a3ea22a1448f340f7a779c5a1274d528..b236e9dcd46854f4f91147a3b03dbf4793c2946c 100644 (file)
@@ -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);
        }
 }
 
index 46c9f2229a18675c6a1ca39528dab2196937c0c5..cc3e1478c5a09b04e1b1f724a381a48844cc5ded 100644 (file)
@@ -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);
        }
 }
 
index b4efb2fb36fa3b875e96e5a668d2f349289e8bad..5032b9d7d9bb2a8532efc99712e26b09d315873b 100644 (file)
@@ -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,
index fb9fe2ef3a6f60059b7f3fee4e89254b4869d52f..a74ac595656f7aadc91c3acd00ce80f0551839f6 100644 (file)
@@ -139,6 +139,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);