CVE-2026-22986CVE-2026-22986是Linux内核GPIO子系统(gpiolib)中的一个竞态条件漏洞。该漏洞存在于gpiochip_add_data_with_key()函数中,当两个驱动程序同时调用该函数时,会产生竞争条件。具体表现为:一个驱动程序可能在gpio_name_to_desc()中遍历srcu保护的链表,而另一个驱动程序刚刚通过gpiodev_add_to_list_unlocked()将其gdev添加到链表中。这导致一个非互斥且非保护的时间窗口出现,其中一个实例在另一个初始化gdev->srcu之前就对其进行解引用和使用,最终导致内核崩溃。该漏洞的CVSS评分为4.7,属于中等严重程度,可导致系统拒绝服务。
该漏洞的根本原因在于Linux内核gpiolib中gdev->srcu初始化时序问题。当两个驱动程序并发调用gpiochip_add_data_with_key()时,会触发以下竞争条件:
1. 驱动程序A调用gpiochip_add_data_with_key()并将gdev添加到gpio_devices链表
2. 驱动程序B同时调用gpiochip_add_data_with_key()
3. 驱动程序A开始遍历srcu保护的链表(在gpio_name_to_desc()中)
4. 驱动程序B在gdev->srcu被初始化之前就尝试访问它
5. 内核产生页错误:Unable to handle kernel paging request
6. 最终导致Oops内核崩溃
漏洞利用栈追踪显示崩溃发生在__srcu_read_lock+0x44和gpio_name_to_desc+0x60处。修复方案是将gdev字段的初始化代码移动到将其添加到gpio_devices链表之前,与相邻的初始化代码放在一起,并调整goto语句以反映修改后的操作顺序。