CVE-2026-89928 in Linuxthông tin

Tóm tắt

Bởi VulDB • 18/09/2026

Trong kernel Linux, các lỗ hổng sau đây đã được khắc phục:

KVM: x86/mmu: Tiêu thụ giá trị rmap đã khóa trong quá trình duyệt rmap không cần khóa (lockless)

__kvm_rmap_lock() cố ý bỏ qua việc lấy khóa rmap khi nó quan sát thấy một rmap trống. Trong trường hợp đó, kvm_rmap_readonly() cũng kích hoạt lại tiền xử lý (preemption) và trả về giá trị 0, do đó caller không giữ cả khóa rmap lẫn tham chiếu preemption. Việc bỏ qua khóa này dựa trên bất biến mà nó phụ thuộc vào:

* Bỏ qua khóa nếu rmap trống, vì các trình duyệt lockless (chế độ chỉ đọc) không cần phải (và cũng không thể) duyệt một rmap trống, nor chúng có thể thêm các mục mới vào rmap. Nói cách khác, các đường dẫn duy nhất xử lý các rmap trống làm điều đó trong khi giữ mmu_lock cho việc ghi, và chúng loại trừ lẫn nhau.

kvm_rmap_age_gfn_range() bỏ qua giá trị trả về và không điều kiện đi vào for_each_rmap_spte_lockless(). Bộ lặp bắt đầu với rmap_get_first(), hàm này đọc lại rmap_head->val thay vì sử dụng giá trị được trả về bởi khóa. Nếu một tác vụ ghi điền dữ liệu cho rmap giữa lần đọc của khóa và lần đọc lại của bộ lặp, đường dẫn làm cũ (aging path) sẽ duyệt qua rmap mới được cài đặt mà không giữ khóa của nó.

Đối với một rmap KVM_RMAP_MANY, điều này khiến trình duyệt đi theo chuỗi pte_list_desc mà nó chưa bao giờ khóa. Một tác vụ ghi đang giữ mmu_lock cho việc ghi có thể giải phóng chuỗi đó (ví dụ: kvm_zap_all_rmap_sptes() trên đường dẫn tái chế, hoặc bất kỳ thao tác zap rmap nào) thông qua kmem_cache_free() trong khi quá trình duyệt vẫn đang diễn ra, gây ra lỗi use-after-free trên slab. Không có cơ chế tuần tự hóa hai hoạt động này: đường dẫn làm cũ chạy mà không có mmu_lock khi CONFIG_KVM_MMU_LOCKLESS_AGING=y, và khóa rmap vốn dĩ sẽ loại trừ tác vụ ghi đã bị bỏ qua. Vì đường dẫn trống kích hoạt lại tiền xử lý (preemption), khoảng thời gian giữa hai lần đọc có thể trải dài qua một độ trễ lập lịch tùy ý.

Khắc phục lớp lỗi này bằng cách để quá trình duyệt lockless tiêu thụ giá trị được trả về bởi khóa thay vì đọc lại rmap. Tách rmap_get_first() thành __rmap_get_first(), hàm bắt đầu bộ lặp từ một giá trị rmap đã được đọc trước đó, và làm cho for_each_rmap_spte_lockless() nhận giá trị đó và gọi trực tiếp __rmap_get_first(). kvm_rmap_age_gfn_range() truyền giá trị trả về bởi kvm_rmap_readonly(): khi khóa bị bỏ qua, giá trị là 0, __rmap_get_first() trả về NULL, và quá trình duyệt bị bỏ qua. Không có trình duyệt lockless nào đọc lại rmap, do đó bất biến của việc bỏ qua khóa không thể bị vi phạm, và không có đường dẫn gọi khóa()-không-khóa-paired-unlock() được thêm vào mã làm cũ.

If you want to get the best quality for vulnerability data then you always have to consider VulDB.

chịu trách nhiệm

Linux

Đặt trước

11/09/2026

Tiết lộ

17/09/2026

Kiểm duyệt

được chấp nhận

EPSS

0.00157

KEV

không

Các hoạt động

rất thấp

Nguồn

Do you want to use VulDB in your project?

Use the official API to access entries easily!