CVE-2026-98087
>_ Opis
Tłumaczenie automatyczne – może zawierać nieścisłości.
W jądrze Linuksa usunięto następującą lukę:
sched/rt,dl: Pomiń zadania wyłączone z migracji podczas wybierania kandydata do wypychania
Zadania RT wywołanego przez migrację_disable() nie można przenieść do innego procesora, ale plik
program planujący nadal utrzymuje takie zadanie na liście możliwych do wypychania tego procesora
(rq->rt.pushable_tasks) i nadal oznacza kolejkę wykonywania RT przeciążoną
(rq->rt.przeciążony = 1). Zatem balanser RT traktuje ten procesor jako
mając zadanie do odsunięcia się i wciąż próbuje je przenieść, ale
pchanie nigdy się nie powiedzie. Kiedy głowa jest przypięta, funkcja push_rt_task() tego nie robi
albo się poddaj. Zamiast tego powraca do pchania rq->curr, używając metody
stoper na procesor, dodany przez zatwierdzenie a7c81556ec4d („sched: Fix
migracja_disable() vs równoważenie rt/dl”).
Procesor spędza dziesiątki milisekund w tej pętli ponawiania prób. Rdzeń jest
izolowany do pracy w czasie rzeczywistym, ale podczas pętli zajmuje prawie połowę czasu
jest pochłaniany przez ataki, które nie mogą zakończyć się sukcesem.
Przechwycenie ftrace procesora, którego dotyczy problem, z włączonym sched_switch i
zatwierdzić 94894c9c477e („sched/rt: Pomiń aktualnie wykonywany procesor w
rto_next_cpu()") pokazuje, gdzie upłynął czas procesora. Dwa SCHED_FIFO
zadania o równym priorytecie współdzielą procesor, zadanieA migracja_disable()'d i
w kolejce, zadanieB jako rq->curr. W jednym oknie trwającym 89 ms zadanie B uzyskało tylko 52 ms
Procesor. Pozostałe 37 ms poszło na gwint zatyczkowy.
Osoba planująca próbowała wypchnąć zadanie A, przypiętą głowę elementu przesuwanego
list, zamiast tego wrócił do pchania zadania B i obudził korek 5204
razy. Każde z tych wypchnięć nie powiodło się i żadne zadanie nie zostało przeniesione. zadanieA
działał, stał w kolejce przez cały czas i nigdy nie działał.
Wypychanie zadania B nie powiodło się przy ponownym sprawdzeniu. find_lock_lowest_rq() upuszcza rq
lock, aby przyjąć docelową blokadę rq, a następnie sprawdza ponownie za pomocą
„zadanie != pick_next_pushable_task(rq)”.
Wypychane zadanie to zadanie B, ale wybór zwraca zadanie A, nagłówek
lista, którą można przesuwać. taskB to rq->curr, a set_next_task_rt() usuwa
uruchamiając zadanie z tej listy, więc zadanie B nigdy nie może być głową. Czek
oczekuje kandydata pobranego z listy możliwej do przesunięcia, ale rezerwowej
naciska rq->curr, którego nigdy nie ma na tej liście. Zatem sprawdzenie kończy się niepowodzeniem
czas.
.--> Nadchodzi push-IPI
| |
| w
| głowica pchana = zadanieA -> przypięta, nie można pchać
| |
| w
| więc zamiast tego wciśnij zadanieB -> obudź migrację/N, klasa zatrzymująca
| | wątek, więc wyprzedza zadanie B
| w
| ponowne sprawdzenie porównuje zadanie B z głowicą pchaną,
| które nadal jest zadaniem A -> poddaj się
| |
| w
| nic się nie poruszyło, zadanie A nadal znajduje się w kolejce, rq nadal jest przeciążone
| |
„---------”
powtarza się co ~17 nas, 5204 razy, przez 89 ms
Pętla nie może się sama zatrzymać. Każda runda opuszcza kolejkę
dokładnie tak, jak było, więc następny push-IPI robi to samo. w
przechwytywanie zakończyło się dopiero wtedy, gdy zadanie B samo poszło spać.
zadanieA zostało następnie wybrane lokalnie i opuściło listę, którą można wypchnąć.
Czas procesora na zadanie w oknie, od sched_switch:
zadanieB 51,95 ms rzeczywista praca
migracja/N 37,18 ms nic się nie poruszyło
zadanieA 0,00 ms w kolejce przez cały czas, nigdy nie wybrane
bezczynność 0,01 ms
Zlicza w tym samym oknie:
Ten procesor obsługuje 7667 push-IPI
17481 pick_next_pushable_task() zwróciło zadanieA, nadal przypięte
5204 find_lock_lowest_rq() zrezygnowała z ponownego sprawdzania
1 naciśnięcie, które faktycznie zostało zakończone
0 migracji zadania A
Czasy procesora i długość okna pochodzą ze standardu
punkt śledzenia sched_switch. Zliczenia wymagały dodania punktów śledzenia
równoważnik RT do tego badania.
Ścieżka self-IPI jest zamykana przez powyższą poprawkę rto_next_cpu() i to
część działa. Ale kolejka runqueue jest nadal oznaczona jako przeciążona, ponieważ
przypięte zadanie jest nadal reklamowane jako możliwe do wypchnięcia. Inne procesory wysyłają teraz plik
push-IPI podczas własnego równoważenia RT i ta sama pętla działa ponownie.
Zamknięcie ścieżki self-IPI nie zatrzymało pinna
---obcięty---
>_ Referencje
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