🔍 CVE-2026-97997

0.0
CVSS Score
UNKNOWN
2026-09-25
2026-10-21 13:21
✅ 완료

🇰🇷 한글 설명

Linux 커널의 virtio_ring에서 packed ring을 사용할 때, descriptor 추가 작업이 실패하더라도 이전에 설정된 AVAIL 및 USED 플래그가 그대로 남아있는 취약점입니다. 이로 인해 잘못된 플래그가 남은 descriptor를 장치가 유효한 명령으로 오인하여 처리하려 시도하게 되고, 결과적으로 큐가 차단되는 현상이 발생합니다.

💡 쉬운 설명

데이터를 전달하는 통로에서 작업이 중간에 실패했을 때, '사용 중'이라는 표시가 지워지지 않고 남아있는 문제입니다. 이 표시 때문에 컴퓨터가 이미 실패한 데이터를 새로운 명령으로 착각하여 시스템이 멈추거나 오류가 발생할 수 있습니다.

🇺🇸 원문 (English)

In the Linux kernel, the following vulnerability has been resolved: virtio_ring: fix stale descriptor flags after a failed packed add In a packed ring the AVAIL and USED bits sit in the descriptor itself, so writing them makes that descriptor available. Those bit combinations flip meaning on every round of the ring, tracked by a wrap counter, so invalidating or validating a descriptor means inverting both bits. Commit 1ce9e6055fa0 ("virtio_ring: introduce packed ring support") has virtqueue_add_packed() make every descriptor of a chain available as it maps the chain, and write the head last. The device consumes the ring in order and stops at a head that is not available yet, so it never reaches the rest. When vring_map_one_sg() fails partway, unmap_release unmaps the segments and restores avail_used_flags, but the descriptors it wrote to in the ring stay marked with AVAIL and USED bits. The head is now the only entry that keeps the device from consuming these stale entries. For example, the ring would look like this now. Z - pre-previous command A - previous command B - aborted command C - current command [A1 DONE] [A2 DONE] <C1 EMPTY> [B2] [B3] [Z1 DONE] When the driver now attempts to issue the C command, the next add starts at the same head as B. If C spans less descriptors than B, there is no end marker because AVAIL and USED bits were still in place. And that means the device will start interpreting these stale entries (B2/B3) as another command entry, which then blocks the queue. This effect typically happens in swiotlb configurations under memory pressure, because vring_map_one_sg() can then fail with larger I/O requests which then leads to command abortions. There are broadly 2 ways to avoid leaving those flags behind: 1) Defer those flags too until the chain is complete. 2) Rewrite those flags for the previous wrap counter. Implement the second option in both packed add paths. The first option traverses the chain a second time on every successful add. The second option invalidates all added descriptors when any add fails. With this patch applied, a packed virtqueue keeps completing requests after a failed add.

📍 영향받는 시스템

Linux kernel (virtio_ring packed ring support introduced in commit 1ce9e6055fa0)

⚔️ 공격 벡터

메모리 압박 상황에서 SWIOTLB 구성 시 대규모 I/O 요청을 유도하여 vring_map_one_sg() 실패를 유발함으로써 발생

🛡️ 대응 방법

커널 패치(commit 1ce9e6055fa0 이후의 수정 사항)를 적용하여 실패 시 descriptor 플래그를 이전 wrap counter로 되돌리도록 업데이트

🔧 검증 코드

출력된 커널 버전이 해당 취약점이 수정된 패치 버전 이후인지 확인

Shell / Script
uname -r

💻 영향받는 소프트웨어

Linux Kernel