[PATCH OLK-5.10 0/3] Fix CVE-2025-39993
1.media: imon: Fix race getting ictx->lock 2.media: imon: grab lock earlier in imon_ir_change_protocol() 3.media: rc: fix races with imon_disconnect() Larshin Sergey (1): media: rc: fix races with imon_disconnect() Ricardo Ribalda (1): media: imon: Fix race getting ictx->lock Tetsuo Handa (1): media: imon: grab lock earlier in imon_ir_change_protocol() drivers/media/rc/imon.c | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) -- 2.25.1
From: Ricardo Ribalda <ribalda@chromium.org> stable inclusion from stable-v5.10.224 commit f3968b3d3cfb8d9d430ab31d18d4553bea206a96 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ID22QN CVE: CVE-2025-39993 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=... -------------------------------- [ Upstream commit 24147897507cd3a7d63745d1518a638bf4132238 ] Lets fix a race between mutex_is_lock() and mutex_lock(). <-mutex is not locked if (!mutex_is_locked(&ictx->lock)) { unlock = true; <- mutex is locked externaly mutex_lock(&ictx->lock); } Let's use mutex_trylock() that does mutex_is_lock() and mutex_lock() atomically. Fix the following cocci warning: drivers/media/rc/imon.c:1167:1-7: preceding lock on line 1153 Fixes: 23ef710e1a6c ("[media] imon: add conditional locking in change_protocol") Signed-off-by: Ricardo Ribalda <ribalda@chromium.org> Signed-off-by: Sean Young <sean@mess.org> Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> Signed-off-by: Sasha Levin <sashal@kernel.org> Signed-off-by: Yi Yang <yiyang13@huawei.com> --- drivers/media/rc/imon.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index 253a1d1a840a..cd4995e74b97 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -1153,10 +1153,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto) memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet)); - if (!mutex_is_locked(&ictx->lock)) { - unlock = true; - mutex_lock(&ictx->lock); - } + unlock = mutex_trylock(&ictx->lock); retval = send_packet(ictx); if (retval) -- 2.25.1
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> mainline inclusion from mainline-v6.18-rc1 commit 7019553ab850ce1d3f0e512e16d14ab153f91c04 category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ID22QN CVE: CVE-2025-39993 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- Move mutex_trylock() in imon_ir_change_protocol() to the beginning, for memcpy() which modifies ictx->usb_tx_buf should be protected by ictx->lock. Also, verify at the beginning of send_packet() that ictx->lock is held in case send_packet() is by error called from imon_ir_change_protocol() when mutex_trylock() failed due to concurrent requests. Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Signed-off-by: Sean Young <sean@mess.org> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org> Signed-off-by: Yi Yang <yiyang13@huawei.com> --- drivers/media/rc/imon.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index cd4995e74b97..fed5434d008d 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -598,6 +598,8 @@ static int send_packet(struct imon_context *ictx) int retval = 0; struct usb_ctrlrequest *control_req = NULL; + lockdep_assert_held(&ictx->lock); + /* Check if we need to use control or interrupt urb */ if (!ictx->tx_control) { pipe = usb_sndintpipe(ictx->usbdev_intf0, @@ -1126,7 +1128,7 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto) int retval; struct imon_context *ictx = rc->priv; struct device *dev = ictx->dev; - bool unlock = false; + const bool unlock = mutex_trylock(&ictx->lock); unsigned char ir_proto_packet[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86 }; @@ -1153,8 +1155,6 @@ static int imon_ir_change_protocol(struct rc_dev *rc, u64 *rc_proto) memcpy(ictx->usb_tx_buf, &ir_proto_packet, sizeof(ir_proto_packet)); - unlock = mutex_trylock(&ictx->lock); - retval = send_packet(ictx); if (retval) goto out; -- 2.25.1
From: Larshin Sergey <Sergey.Larshin@kaspersky.com> mainline inclusion from mainline-v6.18-rc1 commit fa0f61cc1d828178aa921475a9b786e7fbb65ccb category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/ID22QN CVE: CVE-2025-39993 Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- Syzbot reports a KASAN issue as below: BUG: KASAN: use-after-free in __create_pipe include/linux/usb.h:1945 [inline] BUG: KASAN: use-after-free in send_packet+0xa2d/0xbc0 drivers/media/rc/imon.c:627 Read of size 4 at addr ffff8880256fb000 by task syz-executor314/4465 CPU: 2 PID: 4465 Comm: syz-executor314 Not tainted 6.0.0-rc1-syzkaller #0 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.14.0-2 04/01/2014 Call Trace: <TASK> __dump_stack lib/dump_stack.c:88 [inline] dump_stack_lvl+0xcd/0x134 lib/dump_stack.c:106 print_address_description mm/kasan/report.c:317 [inline] print_report.cold+0x2ba/0x6e9 mm/kasan/report.c:433 kasan_report+0xb1/0x1e0 mm/kasan/report.c:495 __create_pipe include/linux/usb.h:1945 [inline] send_packet+0xa2d/0xbc0 drivers/media/rc/imon.c:627 vfd_write+0x2d9/0x550 drivers/media/rc/imon.c:991 vfs_write+0x2d7/0xdd0 fs/read_write.c:576 ksys_write+0x127/0x250 fs/read_write.c:631 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x35/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd The iMON driver improperly releases the usb_device reference in imon_disconnect without coordinating with active users of the device. Specifically, the fields usbdev_intf0 and usbdev_intf1 are not protected by the users counter (ictx->users). During probe, imon_init_intf0 or imon_init_intf1 increments the usb_device reference count depending on the interface. However, during disconnect, usb_put_dev is called unconditionally, regardless of actual usage. As a result, if vfd_write or other operations are still in progress after disconnect, this can lead to a use-after-free of the usb_device pointer. Thread 1 vfd_write Thread 2 imon_disconnect ... if usb_put_dev(ictx->usbdev_intf0) else usb_put_dev(ictx->usbdev_intf1) ... while send_packet if pipe = usb_sndintpipe( ictx->usbdev_intf0) UAF else pipe = usb_sndctrlpipe( ictx->usbdev_intf0, 0) UAF Guard access to usbdev_intf0 and usbdev_intf1 after disconnect by checking ictx->disconnected in all writer paths. Add early return with -ENODEV in send_packet(), vfd_write(), lcd_write() and display_open() if the device is no longer present. Set and read ictx->disconnected under ictx->lock to ensure memory synchronization. Acquire the lock in imon_disconnect() before setting the flag to synchronize with any ongoing operations. Ensure writers exit early and safely after disconnect before the USB core proceeds with cleanup. Found by Linux Verification Center (linuxtesting.org) with Syzkaller. Reported-by: syzbot+f1a69784f6efe748c3bf@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=f1a69784f6efe748c3bf Fixes: 21677cfc562a ("V4L/DVB: ir-core: add imon driver") Cc: stable@vger.kernel.org Signed-off-by: Larshin Sergey <Sergey.Larshin@kaspersky.com> Signed-off-by: Sean Young <sean@mess.org> Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org> Signed-off-by: Yi Yang <yiyang13@huawei.com> --- drivers/media/rc/imon.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/media/rc/imon.c b/drivers/media/rc/imon.c index fed5434d008d..fb6be417e0b2 100644 --- a/drivers/media/rc/imon.c +++ b/drivers/media/rc/imon.c @@ -536,7 +536,9 @@ static int display_open(struct inode *inode, struct file *file) mutex_lock(&ictx->lock); - if (!ictx->display_supported) { + if (ictx->disconnected) { + retval = -ENODEV; + } else if (!ictx->display_supported) { pr_err("display not supported by device\n"); retval = -ENODEV; } else if (ictx->display_isopen) { @@ -600,6 +602,9 @@ static int send_packet(struct imon_context *ictx) lockdep_assert_held(&ictx->lock); + if (ictx->disconnected) + return -ENODEV; + /* Check if we need to use control or interrupt urb */ if (!ictx->tx_control) { pipe = usb_sndintpipe(ictx->usbdev_intf0, @@ -956,12 +961,14 @@ static ssize_t vfd_write(struct file *file, const char __user *buf, static const unsigned char vfd_packet6[] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF }; - if (ictx->disconnected) - return -ENODEV; - if (mutex_lock_interruptible(&ictx->lock)) return -ERESTARTSYS; + if (ictx->disconnected) { + retval = -ENODEV; + goto exit; + } + if (!ictx->dev_present_intf0) { pr_err_ratelimited("no iMON device present\n"); retval = -ENODEV; @@ -1036,11 +1043,13 @@ static ssize_t lcd_write(struct file *file, const char __user *buf, int retval = 0; struct imon_context *ictx = file->private_data; - if (ictx->disconnected) - return -ENODEV; - mutex_lock(&ictx->lock); + if (ictx->disconnected) { + retval = -ENODEV; + goto exit; + } + if (!ictx->display_supported) { pr_err_ratelimited("no iMON display present\n"); retval = -ENODEV; @@ -2502,7 +2511,11 @@ static void imon_disconnect(struct usb_interface *interface) int ifnum; ictx = usb_get_intfdata(interface); + + mutex_lock(&ictx->lock); ictx->disconnected = true; + mutex_unlock(&ictx->lock); + dev = ictx->dev; ifnum = interface->cur_altsetting->desc.bInterfaceNumber; -- 2.25.1
反馈: 您发送到kernel@openeuler.org的补丁/补丁集,已成功转换为PR! PR链接地址: https://gitee.com/openeuler/kernel/pulls/18617 邮件列表地址:https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/APA... FeedBack: The patch(es) which you have sent to kernel@openeuler.org mailing list has been converted to a pull request successfully! Pull request link: https://gitee.com/openeuler/kernel/pulls/18617 Mailing list address: https://mailweb.openeuler.org/archives/list/kernel@openeuler.org/message/APA...
participants (2)
-
patchwork bot -
Yi Yang