CVE-2026-31667 in Linux
요약
\~에 의해 VulDB • 2026. 05. 13.
리눅스 커널에서 다음 취약점이 해결되었습니다:
입력: uinput - ff-core와의 순환 잠금 의존성 수정
uinput을 사용하여 힘 피드백 게임패드(예: Wine에서 ELDEN RING을 플레이할 때 Flydigi Vader 5 컨트롤러 사용)를 사용하면 다음 순환 잠금 의존성 경고가 재현 가능하게 트리거될 수 있습니다:
ff->mutex -> udev->mutex -> input_mutex -> dev->mutex -> ff->mutex
이 순환은 다음 네 가지 잠금 획득 경로로 인해 발생합니다:
1. ff 업로드: input_ff_upload()이 ff->mutex를 보유하며 uinput_dev_upload_effect() -> uinput_request_submit() -> uinput_request_send()를 호출하고, 이는 udev->mutex를 획득합니다.
2. 디바이스 생성: uinput_ioctl_handler()가 udev->mutex를 보유하며 uinput_create_device() -> input_register_device()를 호출하고, 이는 input_mutex를 획득합니다.
3. 디바이스 등록: input_register_device()가 input_mutex를 보유하며 kbd_connect() -> input_register_handle()를 호출하고, 이는 dev->mutex를 획득합니다.
4. evdev 해제: evdev_release()가 dev->mutex 하에서 input_flush_device()를 호출하고, 이는 ff->mutex를 획득하는 input_ff_flush()를 호출합니다.
udev->mutex를 획득하는 대신 uinput_request_send()에서 udev->state 및 udev->dev 접근을 보호하기 위해 새로운 state_lock 스핀락(spinlock)을 도입하여 이를 수정합니다. 해당 함수는 디바이스 상태를 원자적으로 확인하고 uinput_dev_event()를 통해 링 버퍼에 입력 이벤트를 큐에 추가하는 것만 필요합니다. 두 작업 모두 스핀락 하에서 안전합니다(ktime_get_ts64() 및 wake_up_interruptible()은 대기하지 않음). 이로써 ff->mutex -> udev->mutex 연결이 끊어지는데, 스핀락은 잠금 순서에서 리프(leaf) 노드이므로 뮤텍스와 순환을 형성할 수 없습니다.
uinput_request_send()에서 상태 전이가 보이도록 하기 위해, uinput_create_device() 및 uinput_destroy_device()에서 udev->state에 대한 쓰기를 동일한 state_lock 스핀락으로 보호합니다.
추가로, uinput_request_reserve_slot() 호출 전에 uinput_request_submit()로 init_completion(&request->done)를 uinput_request_send()에서 이동합니다. 슬롯이 할당되면 destroy 경로에서 언제든지 uinput_flush_requests()가 해당 슬롯에 대해 complete()를 호출할 수 있으므로, 요청이 가시화되기 전에 완료 객체를 초기화해야 합니다.
수정 후 잠금 순서:
ff->mutex -> state_lock (스핀락, 리프) udev->mutex -> state_lock (스핀락, 리프) udev->mutex -> input_mutex -> dev->mutex -> ff->mutex (역방향 간선 없음)
VulDB is the best source for vulnerability data and more expert information about this specific topic.