CVE-2026-89927
>_ Opis
Tłumaczenie automatyczne – może zawierać nieścisłości.
W jądrze Linuksa usunięto następującą lukę:
KVM: x86: hyper-v: Ostateczny termin timera zacisku, aby uniknąć blokady na żywo
Napraw problem polegający na tym, że przestrzeń użytkownika lub gość może zaprogramować Hyper-V
timer syntetyczny, aby mieć termin w przeszłości poprzez przepełnienie liczb całkowitych,
uniemożliwiając procesorowi postęp i powodując zatrzymanie RCU.
SynIC Hyper-V udostępnia 4 syntetyczne timery na każdy vCPU
gościa, które są emulowane przez KVM. Każdy jest programowany poprzez
HV_X64_MSR_STIMERi_CONFIG i HV_X64_MSR_STIMERi_COUNT MSR. W zależności
w CONFIG, COUNT reprezentuje albo bezwzględny czas wygaśnięcia, albo
okres licznika okresowego, oba wyrażone w odstępach co 100 ns. Te timery
może być ustawiony zarówno przez gościa (WRMSR), jak i hosta (KVM_SET_MSRS).
Gdy timer jest włączony, timer_start() tłumaczy COUNT na
absolutnie monotonny termin i broń hrtimera. Jeśli COUNT jest ustawione na a
wartość bliska U64_MAX, kalkulacja terminu może zostać przekroczona.
ktime_add_ns(ktime_now, 100 * (timer->exp_time - time_now))
Może to spowodować blokadę procesora. timer_start() uzbraja timer
poprzez hrtimer_start() z ostatecznym terminem w przeszłości, co powoduje, że tak jest
natychmiast odpalić. Następnie wywołanie zwrotne timera podnosi KVM_RQ_HV_STIMER, za pomocą
zamiar spowodowania, aby KVM dostarczył syntetyczne przerwanie na serwerze
wejście następnego gościa vCPU.
Następnie, gdy przestrzeń użytkownika wyda KVM_RUN, vcpu_enter_guest() zużywa
żądanie, wywołując kvm_hv_process_stimers(). Zwykle powoduje to wyłączenie
timer za pomocą stimer_expiration(), gdy termin minie w przeszłości.
Jednak porównanie terminów odbywa się pomiędzy referencjami KVM
licznik i stime->exp_time, co jest dużą wartością bliską U64_MAX, więc
coś takiego nie zdarza się nigdy przez kilka tysięcy lat.
kvm_hv_process_timers() następnie ponownie uzbraja timer poprzez stimer_start(), ponieważ
nie został wyłączony, co ponownie uruchamia się natychmiast. Przed wejściem
gość, kvm_vcpu_exit_request() sprawdza kvm_request_pending(),
która zwraca wartość true ze względu na nowo podniesiony KVM_REQ_HV_STIMER. Potem
vcpu_enter_guest() przerywa wpis gościa i wraca wcześniej
vcpu_run(), która wraca do vcpu_enter_guest(), restartując
cykl.
Ponieważ w tej pętli nie ma ręcznych wyników, zadanie z SCHED_FIFO
może zagłodzić wątki okresu karencji RCU, co odsłoni znalezione stragany
przez syzcaller:
rcu: INFO: rcu_preempt wykrył przestoje na procesorach/zadaniach:
rcu: (wykrywany przez 1, t=10502 migi, g=14269, q=1142 ncpus=2)
rcu: Widoczne wszystkie QS, ostatnia aktywność kthread rcu_preempt 10500 (4294965239-4294954739), jiffies_till_next_fqs=1, root ->qsmask 0x0
rcu: rcu_preempt kthread głodny przez 10500 migotów! g14269 f0x2 RCU_GP_WAIT_FQS(5) ->stan=0x0 ->procesor=0
rcu: Jeśli rcu_preempt kthread nie uzyska wystarczającej ilości czasu procesora, oczekiwanym zachowaniem będzie teraz OOM.
(...)
Zadzwoń do śledzenia:
<przerwanie>
__run_hrtimer jądro/time/hrtimer.c:1773 [w linii]
__hrtimer_run_queues+0x408/0xc30 jądro/czas/hrtimer.c:1841
hrtimer_interrupt+0x45b/0xaa0 jądro/time/hrtimer.c:1903
local_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1045 [inline]
__sysvec_apic_timer_interrupt+0x102/0x3e0 arch/x86/kernel/apic/apic.c:1062
instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1056 [inline]
sysvec_apic_timer_interrupt+0xa1/0xc0 arch/x86/kernel/apic/apic.c:1056
</IRQ>
<ZADANIE>
asm_sysvec_apic_timer_interrupt+0x1a/0x20 arch/x86/include/asm/idtentry.h:697
RIP: 0010:__raw_spin_unlock_irqrestore include/linux/spinlock_api_smp.h:152 [inline]
RIP: 0010:_raw_spin_unlock_irqrestore+0xa8/0x110 kernel/locking/spinlock.c:194
Kod: 74 05 e8 0b f4 5f f6 48 c7 44 24 20 00 00 00 00 9c 8f 44 24 20 f6 44 24 21 02 75 4f f7 c3 00 02 00 00 74 01 fb bf 01 00 00 00 <e8> 23 6b 27 f6 65 8b 05 7c 60 5a 07 85 c0 74 40 48 c7 04 24 0e 36
RSP: 0018:ffffc900040a7320 EFLAGS: 00000206
RAX: 5de15cb931505900 RBX: 0000000000000a06 RCX: 5de15cb931505900
RDX: 0000000000000007 RSI: ffffffff8daa9dc3 RDI: 0000000000000001
RBP: ffffc900040a73b0 R08: ffffffff8fc3d0
---obcięty---
>_ Referencje
- https://git.kernel.org/stable/c/0ca49fbd2883cd53d32d85b50feef17fa04d0fbf
- https://git.kernel.org/stable/c/3097582b73a8ed1cd6f6790fa78706f4a79b5a49
- https://git.kernel.org/stable/c/61954727ee08f026f5e1c9ee69e1b404a68f2f7a
- https://git.kernel.org/stable/c/6a8ba9213cce613455b1502ee0fd178656bf617b
- https://git.kernel.org/stable/c/8aa467fe757d8cb2278e98d7fbf44fc05eb0dbf8
- https://git.kernel.org/stable/c/8e19ded84336891646b31375720717635f0fdd90
- https://git.kernel.org/stable/c/a4665762388750e08df99baabe5fce2a21d1423e
- https://git.kernel.org/stable/c/bdb732ebee545b7e3bee7060efc754a8d99818b9
Dane podatności pochodzą z oficjalnych źródeł (CVE® List / NVD). Opisy po polsku są tłumaczone automatycznie i mogą zawierać nieścisłości – na stronie rekordu można wyświetlić wersję angielską.
This product uses the NVD API but is not endorsed or certified by the NVD.
Copyright © 1999–2026, The MITRE Corporation. CVE is a registered trademark and the CVE logo is a registered trademark of The MITRE Corporation.
CVE Usage: MITRE hereby grants you a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Common Vulnerabilities and Exposures (CVE®). Any copy you make for such purposes is authorized provided that you reproduce MITRE's copyright designation and this license in any such copy. ALL DOCUMENTS AND THE INFORMATION CONTAINED THEREIN PROVIDED BY MITRE ARE PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND.
NVD Terms of Use / CVE® Terms of Use / nvd.nist.gov / cve.org