| From dd77b1260f8c2fc98ffbaf6ac11eb5d90601d8fa Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Fri, 15 Apr 2022 23:24:48 +0200 |
| Subject: media: pvrusb2: fix array-index-out-of-bounds in pvr2_i2c_core_init |
| |
| From: Pavel Skripkin <paskripkin@gmail.com> |
| |
| [ Upstream commit 471bec68457aaf981add77b4f590d65dd7da1059 ] |
| |
| Syzbot reported that -1 is used as array index. The problem was in |
| missing validation check. |
| |
| hdw->unit_number is initialized with -1 and then if init table walk fails |
| this value remains unchanged. Since code blindly uses this member for |
| array indexing adding sanity check is the easiest fix for that. |
| |
| hdw->workpoll initialization moved upper to prevent warning in |
| __flush_work. |
| |
| Reported-and-tested-by: syzbot+1a247e36149ffd709a9b@syzkaller.appspotmail.com |
| |
| Fixes: d855497edbfb ("V4L/DVB (4228a): pvrusb2 to kernel 2.6.18") |
| Signed-off-by: Pavel Skripkin <paskripkin@gmail.com> |
| Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> |
| Signed-off-by: Mauro Carvalho Chehab <mchehab@kernel.org> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| drivers/media/usb/pvrusb2/pvrusb2-hdw.c | 7 +++++-- |
| 1 file changed, 5 insertions(+), 2 deletions(-) |
| |
| diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c |
| index 40535db585a0..b868a77a048c 100644 |
| --- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c |
| +++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c |
| @@ -2615,6 +2615,11 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, |
| } while (0); |
| mutex_unlock(&pvr2_unit_mtx); |
| |
| + INIT_WORK(&hdw->workpoll, pvr2_hdw_worker_poll); |
| + |
| + if (hdw->unit_number == -1) |
| + goto fail; |
| + |
| cnt1 = 0; |
| cnt2 = scnprintf(hdw->name+cnt1,sizeof(hdw->name)-cnt1,"pvrusb2"); |
| cnt1 += cnt2; |
| @@ -2626,8 +2631,6 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf, |
| if (cnt1 >= sizeof(hdw->name)) cnt1 = sizeof(hdw->name)-1; |
| hdw->name[cnt1] = 0; |
| |
| - INIT_WORK(&hdw->workpoll,pvr2_hdw_worker_poll); |
| - |
| pvr2_trace(PVR2_TRACE_INIT,"Driver unit number is %d, name is %s", |
| hdw->unit_number,hdw->name); |
| |
| -- |
| 2.35.1 |
| |