| From f2270e4f3ac7f706838bb31f76e230a007ae61f1 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 3 Dec 2021 16:40:30 +0100 |
| Subject: media: saa7146: hexium_gemini: Fix a NULL pointer dereference in |
| hexium_attach() |
| |
| From: Zhou Qingyang <zhou1615@umn.edu> |
| |
| [ Upstream commit 3af86b046933ba513d08399dba0d4d8b50d607d0 ] |
| |
| In hexium_attach(dev, info), saa7146_vv_init() is called to allocate |
| a new memory for dev->vv_data. saa7146_vv_release() will be called on |
| failure of saa7146_register_device(). There is a dereference of |
| dev->vv_data in saa7146_vv_release(), which could lead to a NULL |
| pointer dereference on failure of saa7146_vv_init(). |
| |
| Fix this bug by adding a check of saa7146_vv_init(). |
| |
| This bug was found by a static analyzer. The analysis employs |
| differential checking to identify inconsistent security operations |
| (e.g., checks or kfrees) between two code paths and confirms that the |
| inconsistent operations are not recovered in the current function or |
| the callers, so they constitute bugs. |
| |
| Note that, as a bug found by static analysis, it can be a false |
| positive or hard to trigger. Multiple researchers have cross-reviewed |
| the bug. |
| |
| Builds with CONFIG_VIDEO_HEXIUM_GEMINI=m show no new warnings, |
| and our static analyzer no longer warns about this code. |
| |
| Link: https://lore.kernel.org/linux-media/20211203154030.111210-1-zhou1615@umn.edu |
| Signed-off-by: Zhou Qingyang <zhou1615@umn.edu> |
| Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/media/common/saa7146/saa7146_fops.c | 2 +- |
| drivers/media/pci/saa7146/hexium_gemini.c | 7 ++++++- |
| 2 files changed, 7 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/media/common/saa7146/saa7146_fops.c b/drivers/media/common/saa7146/saa7146_fops.c |
| index d6531874faa65..8047e305f3d01 100644 |
| --- a/drivers/media/common/saa7146/saa7146_fops.c |
| +++ b/drivers/media/common/saa7146/saa7146_fops.c |
| @@ -523,7 +523,7 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) |
| ERR("out of memory. aborting.\n"); |
| kfree(vv); |
| v4l2_ctrl_handler_free(hdl); |
| - return -1; |
| + return -ENOMEM; |
| } |
| |
| saa7146_video_uops.init(dev,vv); |
| diff --git a/drivers/media/pci/saa7146/hexium_gemini.c b/drivers/media/pci/saa7146/hexium_gemini.c |
| index 2214c74bbbf15..3947701cd6c7e 100644 |
| --- a/drivers/media/pci/saa7146/hexium_gemini.c |
| +++ b/drivers/media/pci/saa7146/hexium_gemini.c |
| @@ -284,7 +284,12 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d |
| hexium_set_input(hexium, 0); |
| hexium->cur_input = 0; |
| |
| - saa7146_vv_init(dev, &vv_data); |
| + ret = saa7146_vv_init(dev, &vv_data); |
| + if (ret) { |
| + i2c_del_adapter(&hexium->i2c_adapter); |
| + kfree(hexium); |
| + return ret; |
| + } |
| |
| vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input; |
| vv_data.vid_ops.vidioc_g_input = vidioc_g_input; |
| -- |
| 2.34.1 |
| |