{"api_version":"1","generated_at":"2026-10-27T04:22:48+00:00","cve":"CVE-2026-99050","urls":{"html":"https://cve.report/CVE-2026-99050","api":"https://cve.report/api/cve/CVE-2026-99050.json","docs":"https://cve.report/api","cve_org":"https://www.cve.org/CVERecord?id=CVE-2026-99050","nvd":"https://nvd.nist.gov/vuln/detail/CVE-2026-99050"},"summary":{"title":"gpio: mpsse: fix race when arming the IRQ poll worker","description":"In the Linux kernel, the following vulnerability has been resolved:\n\ngpio: mpsse: fix race when arming the IRQ poll worker\n\ngpio_mpsse_irq_enable() arms the poll worker before publishing it:\nschedule_work() runs before the worker is added to priv->workers. If\ngpio_mpsse_disconnect() walks the list in that window it misses the\nworker, and once disconnect returns, the USB core frees mpsse_priv\nwhile the orphaned gpio_mpsse_poll() work keeps accessing it, causing\na use-after-free.\n\nFix this by publishing and arming the worker in one irq_spin\ncritical section. Teardown walks the same list under irq_spin, so a\nworker found on the list is guaranteed to be armed, and\ncancel_work_sync() handles it whether it is queued or running.\n\nA worker armed after the disconnect walk would still be missed, so\nalso set a new priv->dying flag under irq_spin before the teardown\nwalk, and check it in the same critical section, freeing it via\nkfree_rcu() instead when the device is going away, since kfree()\nwould be called with the IRQ core's raw spinlock held and may sleep\non PREEMPT_RT. schedule_work() is safe to call with irq_spin held,\nand the next probe gets a fresh mpsse_priv, so the flag never needs\nto be cleared.\n\nThis issue was found by an in-house static analysis tool.","state":"PUBLISHED","assigner":"Linux","published_at":"2026-10-23 13:17:28","updated_at":"2026-10-24 14:16:53"},"problem_types":[],"metrics":[{"version":"3.1","source":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","type":"Secondary","score":"7.8","severity":"HIGH","vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","data":{"version":"3.1","vectorString":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","baseScore":7.8,"baseSeverity":"HIGH","attackVector":"LOCAL","attackComplexity":"LOW","privilegesRequired":"LOW","userInteraction":"NONE","scope":"UNCHANGED","confidentialityImpact":"HIGH","integrityImpact":"HIGH","availabilityImpact":"HIGH"}},{"version":"3.1","source":"CNA","type":"DECLARED","score":"7.8","severity":"HIGH","vector":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","data":{"baseScore":7.8,"baseSeverity":"HIGH","vectorString":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","version":"3.1"}}],"references":[{"url":"https://git.kernel.org/stable/c/7efa1a1953cd6b20b23a3524d5b4b81789c6ef25","name":"https://git.kernel.org/stable/c/7efa1a1953cd6b20b23a3524d5b4b81789c6ef25","refsource":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://git.kernel.org/stable/c/76390ac0bca7e5058b7482eb4d951c3bda5df812","name":"https://git.kernel.org/stable/c/76390ac0bca7e5058b7482eb4d951c3bda5df812","refsource":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://git.kernel.org/stable/c/c0071ee496e1228976c72b096f529503222708a0","name":"https://git.kernel.org/stable/c/c0071ee496e1228976c72b096f529503222708a0","refsource":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","tags":[],"title":"","mime":"","httpstatus":"","archivestatus":"0"},{"url":"https://www.cve.org/CVERecord?id=CVE-2026-99050","name":"CVE Program record","refsource":"CVE.ORG","tags":["canonical"]},{"url":"https://nvd.nist.gov/vuln/detail/CVE-2026-99050","name":"NVD vulnerability detail","refsource":"NVD","tags":["canonical","analysis"]}],"affected":[{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected 472d900c8bcac301ae0e40fdca7db799bd989ff5 76390ac0bca7e5058b7482eb4d951c3bda5df812 git","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected 179ef1127d7a4f09f0e741fa9f30b8a8e7886271 c0071ee496e1228976c72b096f529503222708a0 git","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected 179ef1127d7a4f09f0e741fa9f30b8a8e7886271 7efa1a1953cd6b20b23a3524d5b4b81789c6ef25 git","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected 6.18.6 6.18.57 semver","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"affected 6.19","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 6.19 semver","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 6.18.57 6.18.* semver","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 7.2.11 7.2.* semver","platforms":[]},{"source":"CNA","vendor":"Linux","product":"Linux","version":"unaffected 7.3 * original_commit_for_fix","platforms":[]}],"timeline":[],"solutions":[],"workarounds":[],"exploits":[],"credits":[],"nvd_cpes":[],"vendor_comments":[],"enrichments":{"kev":null,"epss":null,"legacy_qids":[]},"source_records":{"cve_program":{"containers":{"cna":{"affected":[{"defaultStatus":"unaffected","product":"Linux","programFiles":["drivers/gpio/gpio-mpsse.c"],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","vendor":"Linux","versions":[{"lessThan":"76390ac0bca7e5058b7482eb4d951c3bda5df812","status":"affected","version":"472d900c8bcac301ae0e40fdca7db799bd989ff5","versionType":"git"},{"lessThan":"c0071ee496e1228976c72b096f529503222708a0","status":"affected","version":"179ef1127d7a4f09f0e741fa9f30b8a8e7886271","versionType":"git"},{"lessThan":"7efa1a1953cd6b20b23a3524d5b4b81789c6ef25","status":"affected","version":"179ef1127d7a4f09f0e741fa9f30b8a8e7886271","versionType":"git"},{"lessThan":"6.18.57","status":"affected","version":"6.18.6","versionType":"semver"}]},{"defaultStatus":"affected","product":"Linux","programFiles":["drivers/gpio/gpio-mpsse.c"],"repo":"https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git","vendor":"Linux","versions":[{"status":"affected","version":"6.19"},{"lessThan":"6.19","status":"unaffected","version":"0","versionType":"semver"},{"lessThanOrEqual":"6.18.*","status":"unaffected","version":"6.18.57","versionType":"semver"},{"lessThanOrEqual":"7.2.*","status":"unaffected","version":"7.2.11","versionType":"semver"},{"lessThanOrEqual":"*","status":"unaffected","version":"7.3","versionType":"original_commit_for_fix"}]}],"cpeApplicability":[{"nodes":[{"cpeMatch":[{"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionEndExcluding":"6.18.57","versionStartIncluding":"6.18.6","vulnerable":true},{"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionEndExcluding":"7.2.11","versionStartIncluding":"6.19","vulnerable":true},{"criteria":"cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*","versionEndExcluding":"7.3","versionStartIncluding":"6.19","vulnerable":true}],"negate":false,"operator":"OR"}]}],"descriptions":[{"lang":"en","value":"In the Linux kernel, the following vulnerability has been resolved:\n\ngpio: mpsse: fix race when arming the IRQ poll worker\n\ngpio_mpsse_irq_enable() arms the poll worker before publishing it:\nschedule_work() runs before the worker is added to priv->workers. If\ngpio_mpsse_disconnect() walks the list in that window it misses the\nworker, and once disconnect returns, the USB core frees mpsse_priv\nwhile the orphaned gpio_mpsse_poll() work keeps accessing it, causing\na use-after-free.\n\nFix this by publishing and arming the worker in one irq_spin\ncritical section. Teardown walks the same list under irq_spin, so a\nworker found on the list is guaranteed to be armed, and\ncancel_work_sync() handles it whether it is queued or running.\n\nA worker armed after the disconnect walk would still be missed, so\nalso set a new priv->dying flag under irq_spin before the teardown\nwalk, and check it in the same critical section, freeing it via\nkfree_rcu() instead when the device is going away, since kfree()\nwould be called with the IRQ core's raw spinlock held and may sleep\non PREEMPT_RT. schedule_work() is safe to call with irq_spin held,\nand the next probe gets a fresh mpsse_priv, so the flag never needs\nto be cleared.\n\nThis issue was found by an in-house static analysis tool."}],"metrics":[{"cvssV3_1":{"baseScore":7.8,"baseSeverity":"HIGH","vectorString":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","version":"3.1"},"scenarios":[{"lang":"en","value":"AV:L - A local process can race GPIO_V2_GET_LINE_IOCTL -> linereq_create() -> edge_detector_setup() -> request_threaded_irq() -> gpio_mpsse_irq_enable() against USBDEVFS_IOCTL/USBDEVFS_DISCONNECT -> usb_driver_release_interface() -> gpio_mpsse_disconnect(); no network input reaches the bug.\nAC:L - The attacker can issue the GPIO line-event request and USBFS unbind concurrently and repeat after rebinding; both sides of the schedule_work()-before-list_add() window are attacker-controlled.\nPR:L - Neither gpio_ioctl() nor the USBDEVFS_DISCONNECT path performs a capability check; the process only needs non-root DAC/ACL access to /dev/gpiochipN and writable access to the matching /dev/bus/usb node.\nUI:N - The same process submits the line-event and USB disconnect ioctls that create the race, so no action by another user is required.\nS:U - The freed mpsse_priv and orphaned gpio_mpsse_poll() worker are both in the host kernel; the path crosses no VM, IOMMU, or other security authority.\nC:H - gpio_mpsse_poll() continues through attacker-reclaimable mpsse_priv fields, including GPIO, IRQ-domain, USB-buffer, and interface pointers; the resulting UAF and write primitive can yield kernel code execution and unrestricted reads.\nI:H - gpio_mpsse_poll() locks and traverses priv->workers after priv is freed; reclaiming that allocation lets controlled list pointers reach list_del(), providing attacker-directed kernel writes and control-flow corruption.\nA:H - The orphaned gpio_mpsse_poll() can access freed mutex, spinlock, and list state, or use the NULL/stale priv->intf in MPSSE I/O, causing an oops or kernel panic."}]}],"providerMetadata":{"dateUpdated":"2026-10-24T14:10:11.370Z","orgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","shortName":"Linux"},"references":[{"url":"https://git.kernel.org/stable/c/76390ac0bca7e5058b7482eb4d951c3bda5df812"},{"url":"https://git.kernel.org/stable/c/c0071ee496e1228976c72b096f529503222708a0"},{"url":"https://git.kernel.org/stable/c/7efa1a1953cd6b20b23a3524d5b4b81789c6ef25"}],"title":"gpio: mpsse: fix race when arming the IRQ poll worker","x_generator":{"engine":"bippy-1.2.0"}}},"cveMetadata":{"assignerOrgId":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","assignerShortName":"Linux","cveId":"CVE-2026-99050","datePublished":"2026-10-23T12:22:29.204Z","dateReserved":"2026-09-25T10:25:14.388Z","dateUpdated":"2026-10-24T14:10:11.370Z","state":"PUBLISHED"},"dataType":"CVE_RECORD","dataVersion":"5.2"},"nvd":{"publishedDate":"2026-10-23 13:17:28","lastModifiedDate":"2026-10-24 14:16:53","problem_types":[],"metrics":{"cvssMetricV31":[{"source":"416baaa9-dc9f-4396-8d5f-8c081fb06d67","type":"Secondary","cvssData":{"version":"3.1","vectorString":"CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H","baseScore":7.8,"baseSeverity":"HIGH","attackVector":"LOCAL","attackComplexity":"LOW","privilegesRequired":"LOW","userInteraction":"NONE","scope":"UNCHANGED","confidentialityImpact":"HIGH","integrityImpact":"HIGH","availabilityImpact":"HIGH"},"exploitabilityScore":1.8,"impactScore":5.9}]},"configurations":[]},"legacy_mitre":{"record":{"CveYear":"2026","CveId":"99050","Ordinal":"1","Title":"gpio: mpsse: fix race when arming the IRQ poll worker","CVE":"CVE-2026-99050","Year":"2026"},"notes":[{"CveYear":"2026","CveId":"99050","Ordinal":"1","NoteData":"In the Linux kernel, the following vulnerability has been resolved:\n\ngpio: mpsse: fix race when arming the IRQ poll worker\n\ngpio_mpsse_irq_enable() arms the poll worker before publishing it:\nschedule_work() runs before the worker is added to priv->workers. If\ngpio_mpsse_disconnect() walks the list in that window it misses the\nworker, and once disconnect returns, the USB core frees mpsse_priv\nwhile the orphaned gpio_mpsse_poll() work keeps accessing it, causing\na use-after-free.\n\nFix this by publishing and arming the worker in one irq_spin\ncritical section. Teardown walks the same list under irq_spin, so a\nworker found on the list is guaranteed to be armed, and\ncancel_work_sync() handles it whether it is queued or running.\n\nA worker armed after the disconnect walk would still be missed, so\nalso set a new priv->dying flag under irq_spin before the teardown\nwalk, and check it in the same critical section, freeing it via\nkfree_rcu() instead when the device is going away, since kfree()\nwould be called with the IRQ core's raw spinlock held and may sleep\non PREEMPT_RT. schedule_work() is safe to call with irq_spin held,\nand the next probe gets a fresh mpsse_priv, so the flag never needs\nto be cleared.\n\nThis issue was found by an in-house static analysis tool.","Type":"Description","Title":"gpio: mpsse: fix race when arming the IRQ poll worker"}]}}}