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 11:09:40 +0000 (13:09 +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 989ae997f66de8ccb174af33016556583294ef45..89b9293b31bef597b528814d0a95b4132050a49c 100644 (file)
@@ -123,6 +123,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 bedc04a72e97e01f540c83283aaae4e786445339..bde4441f935e79ff1414bc474f47af0bd1d88d15 100644 (file)
@@ -1581,6 +1581,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 10fcbe9e8614b2f0d1d064a72573ac806309a43f..cb41e61d50dd31d695f261e1d2959fbc963d84dc 100644 (file)
@@ -2083,6 +2083,11 @@ static int reg_r(struct sd *sd, u16 index)
        } else {
                gspca_err(gspca_dev, "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;
@@ -2111,6 +2116,11 @@ static int reg_r8(struct sd *sd,
        } else {
                gspca_err(gspca_dev, "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 d06dc0755b9a5586f93434a47440be353ee1e660..9e3326b66c7922fe067a9f6f2d7c4e01d3125b10 100644 (file)
@@ -642,6 +642,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 3d1364d2f83e628d0b80adca5f683cf4d05b0003..4d4ae22e96406c53ee59a25871c46fbc294b4a62 100644 (file)
@@ -1154,6 +1154,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 477da0664b7daf1a77537c6314c22bcb7778550d..40b87717bb5c5ab76e13970aead7d04b2520d361 100644 (file)
@@ -111,6 +111,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 cfa2a04d9f3f6a90cb4c34fd32f32c6f15ba3583..a4ae0298185868647728c2772f6eae3d5c80023b 100644 (file)
@@ -918,6 +918,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 5f3f2979540a64b7a868dd2573db3c329a6e08da..22de65d840dd3d980b5725b45762c02e9a1e6714 100644 (file)
@@ -462,6 +462,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 df8d8482b79599974b5465b1fd4a995e02bcfb90..fa108ce000ad6e77143c97ed8769f87e958f7978 100644 (file)
@@ -1171,6 +1171,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 d25924e430f37b8a3f2c9af0fb208db0079491be..a20eb8580db2ea944100ecfd32ecafc9825f49eb 100644 (file)
@@ -80,6 +80,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 d7cbcf2b394794ac8d51529da921c2c51eb14065..3521f5ff428e9e28f545835497f5334cd0bd03a6 100644 (file)
@@ -434,6 +434,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 437a3367ab97488734b88685341a1eb8085aa98f..26eae69a2562f565a51f8f41895cbd44a2bb12f4 100644 (file)
@@ -264,6 +264,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 52d0716596343dbd44a93b444f6c48abdc16dee9..6e32264d3825a5e744c8ed5de9c35f317c41131a 100644 (file)
@@ -2915,6 +2915,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 abfab3de18662b1ed60499538e3fbe0f5c88664c..ef0a839f9b8aeccf5e61a5fe6d9fbe9bf1e8ed20 100644 (file)
@@ -143,6 +143,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);