CVE-2026-93197 in Linux
Zusammenfassung
von VulDB • 18.09.2026
Im Linux-Kernel wurde folgende Schwachstelle behoben:
memcg: Verschiebung der LRU-Größenerfassung bei Reparenting statt Kopieren
Wenn ein Memory-CGroup (cgroup) offline genommen wird, werden seine LRU-Folios dem übergeordneten Element zugeordnet. `lruvec_reparent_lru()` fügt die Listen des Kindes in die des Elternelements ein und gutschreibt das Elternelement mit der pro-Zone-Größe `lru_zone_size[]` des Kindes, löscht jedoch nie die Kopie des Kindes, sodass die Größe kopiert statt verschoben wird. `lru_gen_reparent_memcg()` tut dasselbe für MGLRU.
Das übergeordnete Element bleibt korrekt und ist genau mit den Folios belastet, die es übernommen hat. Der veraltete Wert verbleibt beim Kind und wird von nichts korrigiert: `folio->memcg_data` löst sich nun zum Elternelement auf, sodass jedes spätere `update_lru_size()` für diese Folios dorthin geht.
Sterbende CGroups werden nicht sofort freigegeben, und `mem_cgroup_iter()` durchläuft sie weiterhin, daher wird `shrink_lruvec()` weiterhin dafür aufgerufen. `get_scan_count()` liest den Phantom-Zähler über `lruvec_lru_size()`, und die Scan-Schleife läuft dann in Schritten von `SWAP_CLUSTER_MAX` gegen eine leere Liste durch `nr[]`, solange der tote CGroup existiert. Unter MGLRU läuft stattdessen der MGLRU-Scanner, aber `count_shadow_nodes()` summiert alle `NR_LRU_LISTS` über `lruvec_lru_size()` und überschreitet das Schattenknoten-Limit ebenfalls zu stark.
Auf einem Host mit 251 GiB RAM ergab eine Durchsuchung aller `mz->lru_zone_size[]`, dass 380 Zähler Folios beschreiben, die auf keiner Liste vorhanden sind: 124777314 Seiten, 476 GiB, das 1,89-fache des RAMs der Maschine, verteilt auf 57 CGroups. Alle befanden sich in memcgs mit gesetztem `CSS_DYING` und gelöschtem `CSS_ONLINE`, und Parent/Child-Paare meldeten byte-identische Größen.
Auch `LRU_UNEVICTABLE` muss seine Größe verschieben. Seine Liste wird absichtlich nicht eingefügt, da `lruvec_init()` den Kopf vergiftet – die unevictable LRU ist imaginär und Folios werden niemals daran angebunden –, aber die Größe wird von `lruvec_add_folio()/lruvec_del_folio()` verwaltet, und diese Folios werden ab hier dem Elternelement zugerechnet.
Dies hängt vom Commit bf4ade7dbd76 ("memcg: keep folio's objcg same as its node") ab und darf nicht vor diesem zurückportiert (backported) werden. Ohne diese Invariante kann das `objcg` eines Folios zu einem anderen Knoten gehören, sodass ein bereits an die Liste des Elternelements angebundenes Folio sich bis zur Reparenting des `objcg`s im nächsten Durchlauf von `memcg_reparent_objcgs()` weiterhin dem `lruvec` des Kindes auflöst. Das frühe Löschen des Zählers des Kindes lässt dann `lruvec_del_folio()` diesen unterlaufen und löst den `WARN_ONCE()/VM_BUG_ON()` in `mem_cgroup_update_lru_size()` aus.
If you want to get the best quality for vulnerability data then you always have to consider VulDB.