CVE-2026-31667 (GCVE-0-2026-31667)
Vulnerability from cvelistv5
Published
2026-04-24 14:45
Modified
2026-04-27 14:04
Summary
In the Linux kernel, the following vulnerability has been resolved: Input: uinput - fix circular locking dependency with ff-core A lockdep circular locking dependency warning can be triggered reproducibly when using a force-feedback gamepad with uinput (for example, playing ELDEN RING under Wine with a Flydigi Vader 5 controller): ff->mutex -> udev->mutex -> input_mutex -> dev->mutex -> ff->mutex The cycle is caused by four lock acquisition paths: 1. ff upload: input_ff_upload() holds ff->mutex and calls uinput_dev_upload_effect() -> uinput_request_submit() -> uinput_request_send(), which acquires udev->mutex. 2. device create: uinput_ioctl_handler() holds udev->mutex and calls uinput_create_device() -> input_register_device(), which acquires input_mutex. 3. device register: input_register_device() holds input_mutex and calls kbd_connect() -> input_register_handle(), which acquires dev->mutex. 4. evdev release: evdev_release() calls input_flush_device() under dev->mutex, which calls input_ff_flush() acquiring ff->mutex. Fix this by introducing a new state_lock spinlock to protect udev->state and udev->dev access in uinput_request_send() instead of acquiring udev->mutex. The function only needs to atomically check device state and queue an input event into the ring buffer via uinput_dev_event() -- both operations are safe under a spinlock (ktime_get_ts64() and wake_up_interruptible() do not sleep). This breaks the ff->mutex -> udev->mutex link since a spinlock is a leaf in the lock ordering and cannot form cycles with mutexes. To keep state transitions visible to uinput_request_send(), protect writes to udev->state in uinput_create_device() and uinput_destroy_device() with the same state_lock spinlock. Additionally, move init_completion(&request->done) from uinput_request_send() to uinput_request_submit() before uinput_request_reserve_slot(). Once the slot is allocated, uinput_flush_requests() may call complete() on it at any time from the destroy path, so the completion must be initialised before the request becomes visible. Lock ordering after the fix: ff->mutex -> state_lock (spinlock, leaf) udev->mutex -> state_lock (spinlock, leaf) udev->mutex -> input_mutex -> dev->mutex -> ff->mutex (no back-edge)
Impacted products
Vendor Product Version
Linux Linux Version: ff462551235d8d7d843a005950bc90924fcedede
Version: ff462551235d8d7d843a005950bc90924fcedede
Version: ff462551235d8d7d843a005950bc90924fcedede
Version: ff462551235d8d7d843a005950bc90924fcedede
Version: ff462551235d8d7d843a005950bc90924fcedede
Version: ff462551235d8d7d843a005950bc90924fcedede
Version: ff462551235d8d7d843a005950bc90924fcedede
Version: ff462551235d8d7d843a005950bc90924fcedede
Create a notification for this product.
Show details on NVD website


{
  "containers": {
    "cna": {
      "affected": [
        {
          "defaultStatus": "unaffected",
          "product": "Linux",
          "programFiles": [
            "drivers/input/misc/uinput.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "lessThan": "71a9729f412e2c692a35c542e14b706fb342927f",
              "status": "affected",
              "version": "ff462551235d8d7d843a005950bc90924fcedede",
              "versionType": "git"
            },
            {
              "lessThan": "271ee71a1917b89f6d73ec82dd091c33d92ee617",
              "status": "affected",
              "version": "ff462551235d8d7d843a005950bc90924fcedede",
              "versionType": "git"
            },
            {
              "lessThan": "974f7b138c3a96dd5cd53d1b33409cd7b2229dc6",
              "status": "affected",
              "version": "ff462551235d8d7d843a005950bc90924fcedede",
              "versionType": "git"
            },
            {
              "lessThan": "546c18a14924eb521fe168d916d7ce28f1e13c1d",
              "status": "affected",
              "version": "ff462551235d8d7d843a005950bc90924fcedede",
              "versionType": "git"
            },
            {
              "lessThan": "a3d6c9c053c9c605651508569230ead633b13f76",
              "status": "affected",
              "version": "ff462551235d8d7d843a005950bc90924fcedede",
              "versionType": "git"
            },
            {
              "lessThan": "1e09dfbb4f5d20ee111f92325a00f85778a5f328",
              "status": "affected",
              "version": "ff462551235d8d7d843a005950bc90924fcedede",
              "versionType": "git"
            },
            {
              "lessThan": "1534661043c434b81cfde26b97a2fb2460329cf0",
              "status": "affected",
              "version": "ff462551235d8d7d843a005950bc90924fcedede",
              "versionType": "git"
            },
            {
              "lessThan": "4cda78d6f8bf2b700529f2fbccb994c3e826d7c2",
              "status": "affected",
              "version": "ff462551235d8d7d843a005950bc90924fcedede",
              "versionType": "git"
            }
          ]
        },
        {
          "defaultStatus": "affected",
          "product": "Linux",
          "programFiles": [
            "drivers/input/misc/uinput.c"
          ],
          "repo": "https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git",
          "vendor": "Linux",
          "versions": [
            {
              "status": "affected",
              "version": "2.6.19"
            },
            {
              "lessThan": "2.6.19",
              "status": "unaffected",
              "version": "0",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "5.10.*",
              "status": "unaffected",
              "version": "5.10.253",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "5.15.*",
              "status": "unaffected",
              "version": "5.15.203",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.1.*",
              "status": "unaffected",
              "version": "6.1.169",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.6.*",
              "status": "unaffected",
              "version": "6.6.135",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.12.*",
              "status": "unaffected",
              "version": "6.12.82",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.18.*",
              "status": "unaffected",
              "version": "6.18.23",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "6.19.*",
              "status": "unaffected",
              "version": "6.19.13",
              "versionType": "semver"
            },
            {
              "lessThanOrEqual": "*",
              "status": "unaffected",
              "version": "7.0",
              "versionType": "original_commit_for_fix"
            }
          ]
        }
      ],
      "cpeApplicability": [
        {
          "nodes": [
            {
              "cpeMatch": [
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "5.10.253",
                  "versionStartIncluding": "2.6.19",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "5.15.203",
                  "versionStartIncluding": "2.6.19",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.1.169",
                  "versionStartIncluding": "2.6.19",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.6.135",
                  "versionStartIncluding": "2.6.19",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.12.82",
                  "versionStartIncluding": "2.6.19",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.18.23",
                  "versionStartIncluding": "2.6.19",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "6.19.13",
                  "versionStartIncluding": "2.6.19",
                  "vulnerable": true
                },
                {
                  "criteria": "cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:*",
                  "versionEndExcluding": "7.0",
                  "versionStartIncluding": "2.6.19",
                  "vulnerable": true
                }
              ],
              "negate": false,
              "operator": "OR"
            }
          ]
        }
      ],
      "descriptions": [
        {
          "lang": "en",
          "value": "In the Linux kernel, the following vulnerability has been resolved:\n\nInput: uinput - fix circular locking dependency with ff-core\n\nA lockdep circular locking dependency warning can be triggered\nreproducibly when using a force-feedback gamepad with uinput (for\nexample, playing ELDEN RING under Wine with a Flydigi Vader 5\ncontroller):\n\n  ff-\u003emutex -\u003e udev-\u003emutex -\u003e input_mutex -\u003e dev-\u003emutex -\u003e ff-\u003emutex\n\nThe cycle is caused by four lock acquisition paths:\n\n1. ff upload: input_ff_upload() holds ff-\u003emutex and calls\n   uinput_dev_upload_effect() -\u003e uinput_request_submit() -\u003e\n   uinput_request_send(), which acquires udev-\u003emutex.\n\n2. device create: uinput_ioctl_handler() holds udev-\u003emutex and calls\n   uinput_create_device() -\u003e input_register_device(), which acquires\n   input_mutex.\n\n3. device register: input_register_device() holds input_mutex and\n   calls kbd_connect() -\u003e input_register_handle(), which acquires\n   dev-\u003emutex.\n\n4. evdev release: evdev_release() calls input_flush_device() under\n   dev-\u003emutex, which calls input_ff_flush() acquiring ff-\u003emutex.\n\nFix this by introducing a new state_lock spinlock to protect\nudev-\u003estate and udev-\u003edev access in uinput_request_send() instead of\nacquiring udev-\u003emutex.  The function only needs to atomically check\ndevice state and queue an input event into the ring buffer via\nuinput_dev_event() -- both operations are safe under a spinlock\n(ktime_get_ts64() and wake_up_interruptible() do not sleep).  This\nbreaks the ff-\u003emutex -\u003e udev-\u003emutex link since a spinlock is a leaf in\nthe lock ordering and cannot form cycles with mutexes.\n\nTo keep state transitions visible to uinput_request_send(), protect\nwrites to udev-\u003estate in uinput_create_device() and\nuinput_destroy_device() with the same state_lock spinlock.\n\nAdditionally, move init_completion(\u0026request-\u003edone) from\nuinput_request_send() to uinput_request_submit() before\nuinput_request_reserve_slot().  Once the slot is allocated,\nuinput_flush_requests() may call complete() on it at any time from\nthe destroy path, so the completion must be initialised before the\nrequest becomes visible.\n\nLock ordering after the fix:\n\n  ff-\u003emutex -\u003e state_lock (spinlock, leaf)\n  udev-\u003emutex -\u003e state_lock (spinlock, leaf)\n  udev-\u003emutex -\u003e input_mutex -\u003e dev-\u003emutex -\u003e ff-\u003emutex (no back-edge)"
        }
      ],
      "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"
          }
        }
      ],
      "providerMetadata": {
        "dateUpdated": "2026-04-27T14:04:51.563Z",
        "orgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
        "shortName": "Linux"
      },
      "references": [
        {
          "url": "https://git.kernel.org/stable/c/71a9729f412e2c692a35c542e14b706fb342927f"
        },
        {
          "url": "https://git.kernel.org/stable/c/271ee71a1917b89f6d73ec82dd091c33d92ee617"
        },
        {
          "url": "https://git.kernel.org/stable/c/974f7b138c3a96dd5cd53d1b33409cd7b2229dc6"
        },
        {
          "url": "https://git.kernel.org/stable/c/546c18a14924eb521fe168d916d7ce28f1e13c1d"
        },
        {
          "url": "https://git.kernel.org/stable/c/a3d6c9c053c9c605651508569230ead633b13f76"
        },
        {
          "url": "https://git.kernel.org/stable/c/1e09dfbb4f5d20ee111f92325a00f85778a5f328"
        },
        {
          "url": "https://git.kernel.org/stable/c/1534661043c434b81cfde26b97a2fb2460329cf0"
        },
        {
          "url": "https://git.kernel.org/stable/c/4cda78d6f8bf2b700529f2fbccb994c3e826d7c2"
        }
      ],
      "title": "Input: uinput - fix circular locking dependency with ff-core",
      "x_generator": {
        "engine": "bippy-1.2.0"
      }
    }
  },
  "cveMetadata": {
    "assignerOrgId": "416baaa9-dc9f-4396-8d5f-8c081fb06d67",
    "assignerShortName": "Linux",
    "cveId": "CVE-2026-31667",
    "datePublished": "2026-04-24T14:45:15.937Z",
    "dateReserved": "2026-03-09T15:48:24.129Z",
    "dateUpdated": "2026-04-27T14:04:51.563Z",
    "state": "PUBLISHED"
  },
  "dataType": "CVE_RECORD",
  "dataVersion": "5.2"
}


Log in or create an account to share your comment.




Tags
Taxonomy of the tags.


Loading…

Loading…

Loading…

Sightings

Author Source Type Date

Nomenclature

  • Seen: The vulnerability was mentioned, discussed, or seen somewhere by the user.
  • Confirmed: The vulnerability is confirmed from an analyst perspective.
  • Published Proof of Concept: A public proof of concept is available for this vulnerability.
  • Exploited: This vulnerability was exploited and seen by the user reporting the sighting.
  • Patched: This vulnerability was successfully patched by the user reporting the sighting.
  • Not exploited: This vulnerability was not exploited or seen by the user reporting the sighting.
  • Not confirmed: The user expresses doubt about the veracity of the vulnerability.
  • Not patched: This vulnerability was not successfully patched by the user reporting the sighting.


Loading…

Loading…