IPBUF安全漏洞报告
English
CVE-2023-53580 CVSS 5.5 中危

CVE-2023-53580 Linux内核USB Gadget核心UVC解配置死锁漏洞

披露日期: 2025-10-04
来源: 416baaa9-dc9f-4396-8d5f-8c081fb06d67

漏洞信息

漏洞编号
CVE-2023-53580
漏洞类型
死锁/内核panic
CVSS评分
5.5 中危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux Kernel USB Gadget Core

相关标签

Linux KernelUSB GadgetUVC死锁内核panic本地提权拒绝服务可用性影响CVE-2023-53580内核漏洞

漏洞概述

CVE-2023-53580是Linux内核USB Gadget核心子系统中存在的一个高可用性影响漏洞。该漏洞由Avichal Rakesh报告,涉及USB Gadget框架在UVC(USB Video Class)gadget驱动从gadget配置中移除时触发的内核panic问题。

在Linux内核的USB Gadget核心中,gadget_unbind_driver()函数在调用驱动的->unbind()回调时持有udc->connect_lock互斥锁。然而,当gadget驱动的unbind过程中调用usb_gadget_deactivate()函数时,该函数会尝试获取同一把互斥锁,从而导致死锁问题。这种死锁最终会引发内核panic,造成系统不可用。

该漏洞的根本原因在于代码设计上的不一致性:->bind()回调在调用时不持有互斥锁,而->unbind()回调却持有互斥锁。这种不一致性使得在unbind过程中调用usb_gadget_deactivate()或usb_gadget_activate()成为不可能,因为这些函数需要在进程上下文中运行并获取connect_lock。

该漏洞的CVSS评分为5.5,属于中危级别。虽然利用条件需要本地低权限访问且无需用户交互,但由于其可能导致系统完全不可用(高可用性影响),仍然是一个需要关注的安全问题。漏洞影响范围涵盖多个Linux内核稳定版本,需要通过内核补丁进行修复。

技术细节

从技术层面分析,该漏洞的核心问题在于USB Gadget核心代码中的锁管理不当。

漏洞原理:
在drivers/usb/gadget/udc/core.c中,gadget_unbind_driver()函数的实现存在锁顺序问题。该函数在调用driver->unbind()回调前后都持有udc->connect_lock互斥锁。然而,usb_gadget_deactivate()函数内部需要获取同一个互斥锁(udc->connect_lock),以确保在停用gadget期间不会有并发的连接操作。

当UVC gadget驱动的unbind回调中调用usb_gadget_deactivate()时,会形成自死锁:
1. gadget_unbind_driver()获取connect_lock
2. 调用driver->unbind()
3. unbind()内部调用usb_gadget_deactivate()
4. usb_gadget_deactivate()尝试获取connect_lock
5. 由于该锁已被持有,线程进入等待状态,形成死锁

利用方式:
该漏洞的触发需要满足以下条件:
1. 系统使用USB Gadget框架(常见于嵌入式设备、Android设备等)
2. 配置了UVC功能(将设备模拟为USB摄像头)
3. 本地低权限用户能够触发UVC gadget驱动的解绑操作
4. 在解绑过程中,驱动代码调用了usb_gadget_deactivate()

修复方案:
内核开发者采用的修复方案是在gadget_unbind_driver()中调用->unbind()回调之前释放connect_lock互斥锁,调用完成后再重新获取。这样既保持了调用->bind()和->unbind()时的一致性(都不持有锁),又避免了死锁问题。同时,在usb_gadget_activate()和usb_gadget_deactivate()函数中添加了注释,说明这两个函数必须在进程上下文中调用,不能从可能运行在中断上下文中的->disconnect()回调中调用。

攻击链分析

STEP 1
步骤1:环境准备
攻击者需要在运行受影响Linux内核的系统上获得本地低权限访问权限。系统需要启用USB Gadget框架支持,并且配置了UVC(USB Video Class)功能模块(如嵌入式开发板、Android设备等)。
STEP 2
步骤2:加载UVC Gadget驱动
系统加载UVC gadget驱动模块(如g_uvc),将设备配置为USB Video Class设备。此时USB Gadget核心会调用驱动的->bind()回调完成初始化。
STEP 3
步骤3:触发解配置操作
当UVC gadget驱动从gadget配置中移除时(例如通过rmmod卸载模块或通过configfs修改配置),USB Gadget核心的gadget_unbind_driver()函数被调用。
STEP 4
步骤4:死锁触发
gadget_unbind_driver()在持有udc->connect_lock互斥锁的情况下调用驱动的->unbind()回调。如果驱动在unbind过程中调用usb_gadget_deactivate(),该函数尝试获取已被持有的connect_lock,导致死锁。
STEP 5
步骤5:系统不可用
死锁导致内核进入不可恢复状态,触发内核panic(softlockup检测或hung task检测),系统变得不可用,需要重启恢复。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
// CVE-2023-53580 PoC - Triggering USB Gadget UVC Unconfigure Deadlock // This PoC demonstrates the deadlock condition in USB Gadget core // when usb_gadget_deactivate() is called during UVC gadget unbind. #include <linux/module.h> #include <linux/kernel.h> #include <linux/usb/gadget.h> #include <linux/mutex.h> // Simulated UVC gadget driver unbind callback that triggers the deadlock static int uvc_gadget_unbind(struct usb_gadget *gadget) { struct usb_gadget_driver *driver = container_of( gadget->dev.driver, struct usb_gadget_driver, driver); pr_info("UVC gadget unbind called\n"); // This call will attempt to acquire udc->connect_lock // which is already held by gadget_unbind_driver(), // causing a deadlock and subsequent kernel panic. usb_gadget_deactivate(gadget); return 0; } static int uvc_gadget_bind(struct usb_gadget *gadget) { pr_info("UVC gadget bind called\n"); return 0; } static struct usb_gadget_driver uvc_gadget_driver = { .function = "uvc", .bind = uvc_gadget_bind, .unbind = uvc_gadget_unbind, .name = "g_uvc", }; static int __init uvc_poc_init(void) { int ret; pr_info("Loading CVE-2023-53580 PoC module\n"); // Register the UVC gadget driver ret = usb_gadget_register_driver(&uvc_gadget_driver); if (ret) { pr_err("Failed to register gadget driver: %d\n", ret); return ret; } pr_info("UVC gadget driver registered successfully\n"); return 0; } static void __exit uvc_poc_exit(void) { pr_info("Unloading CVE-2023-53580 PoC module\n"); // This will trigger the deadlock: // gadget_unbind_driver() holds connect_lock // -> uvc_gadget_unbind() calls usb_gadget_deactivate() // -> usb_gadget_deactivate() tries to acquire connect_lock // -> DEADLOCK -> kernel panic usb_gadget_unregister_driver(&uvc_gadget_driver); } module_init(uvc_poc_init); module_exit(uvc_poc_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Security Researcher"); MODULE_DESCRIPTION("PoC for CVE-2023-53580 - USB Gadget UVC Unconfigure Deadlock"); MODULE_VERSION("1.0");

影响范围

Linux Kernel < 6.6 (需要根据具体补丁版本确认)
Linux Kernel stable分支需要应用补丁: 65dadb2beeb7360232b09ebc4585b54475dfee06
Linux Kernel stable分支需要应用补丁: 8c1edc00db65f6d4408b3d1cd845e8da3b9e0ca4
Linux Kernel stable分支需要应用补丁: bed19d95fcb9c98dfaa9585922b39a2dfba7898d

防御指南

临时缓解措施
在无法立即升级内核的情况下,可以采取以下临时缓解措施:1)如果系统不需要UVC功能,可以通过内核配置(CONFIG_USB_CONFIGFS_UVC=n)禁用UVC gadget支持;2)限制普通用户对configfs的访问权限,仅允许特权用户操作USB Gadget配置;3)监控系统状态,及时发现并处理可能的死锁情况;4)避免在生产环境中频繁动态加载/卸载UVC gadget驱动模块。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表