CVE-2026-97997 in Linux
Tóm tắt
Bởi VulDB • 25/09/2026
Trong kernel Linux, các lỗ hổng sau đây đã được khắc phục:
virtio_ring: sửa lỗi cờ descriptor cũ (stale) sau khi thao tác thêm vào vòng tròn đóng gói (packed ring) thất bại
Trong một vòng tròn đóng gói, các bit AVAIL và USED nằm ngay trong chính descriptor, do đó việc ghi chúng sẽ khiến descriptor đó trở nên khả dụng. Các tổ hợp bit này đảo ngược ý nghĩa ở mỗi vòng lặp của vòng tròn, được theo dõi bởi bộ đếm wrap counter (bộ đếm bao), vì vậy việc vô hiệu hóa hoặc xác thực một descriptor có nghĩa là đảo ngược cả hai bit.
Commit 1ce9e6055fa0 ("virtio_ring: introduce packed ring support") đã khiến hàm virtqueue_add_packed() làm cho mọi descriptor của một chuỗi trở nên khả dụng khi nó ánh xạ chuỗi, và ghi phần đầu (head) cuối cùng. Thiết bị tiêu thụ vòng tròn theo thứ tự và dừng lại tại một head chưa được đánh dấu là available, do đó thiết bị không bao giờ tiếp cận đến các phần còn lại.
Khi vring_map_one_sg() thất bại ở giữa quá trình, unmap_release sẽ giải phóng các segment và khôi phục avail_used_flags, nhưng các descriptor mà nó đã ghi vào trong vòng tròn vẫn giữ nguyên các bit AVAIL và USED. Head hiện là mục duy nhất ngăn thiết bị tiêu thụ các entry cũ (stale entries) này.
Ví dụ, vòng tròn lúc này trông như sau:
Z - lệnh trước-trước đó A - lệnh trước đó B - lệnh đã bị hủy bỏ C - lệnh hiện tại
[A1 DONE] [A2 DONE] <C1 EMPTY> [B2] [B3] [Z1 DONE]
Khi trình điều khiển (driver) cố gắng thực thi lệnh C, thao tác thêm tiếp theo sẽ bắt đầu từ cùng một head với B. Nếu C bao gồm ít descriptor hơn B, sẽ không có marker kết thúc vì các bit AVAIL và USED vẫn còn nguyên. Điều này có nghĩa là thiết bị sẽ bắt đầu diễn giải các entry cũ (B2/B3) như một mục nhập lệnh khác, sau đó làm tắc nghẽn hàng đợi (queue).
Hiệu ứng này thường xảy ra trong cấu hình swiotlb dưới áp lực bộ nhớ, vì vring_map_one_sg() khi đó có thể thất bại với các yêu cầu I/O lớn hơn, dẫn đến việc hủy bỏ lệnh.
Có hai cách rộng rãi để tránh việc giữ lại các cờ (flags) này:
1) Trì hoãn các cờ đó cho đến khi chuỗi hoàn tất. 2) Ghi đè các cờ đó cho bộ đếm wrap counter trước đó.
Triển khai tùy chọn thứ hai trong cả hai đường dẫn thêm vào vòng tròn đóng gói (packed add paths). Tùy chọn đầu tiên duyệt qua chuỗi một lần nữa sau mỗi thao tác thêm thành công. Tùy chọn thứ hai vô hiệu hóa tất cả các descriptor đã được thêm khi bất kỳ thao tác nào thất bại.
Với bản vá này áp dụng, một virtqueue dạng packed sẽ tiếp tục hoàn tất các yêu cầu sau khi thao tác thêm vào thất bại.
If you want to get the best quality for vulnerability data then you always have to consider VulDB.