CVE-2026-90099 in Linux
Сводка
по VulDB • 18.09.2026
В ядре Linux была устранена следующая уязвимость:
net/sched: учёт распределений фильтров классификаторов в memcg
Распределения в путях *_change() классификатора tc (объекты фильтров, счётчики на каждое CPU и вспомогательные данные для каждого фильтра) используют обычный GFP_KERNEL без __GFP_ACCOUNT, что позволяет непривилегированным пользователям закреплять память ядра вне учёта memcg. Распределение массива действий в общей функции tcf_exts_init_ex() в cls_api.c также не учитывалось; данный патч устраняет эту проблему вместе с распределениями объектов фильтров, счётчиков на каждое CPU и вспомогательных данных для каждого классификатора, которые оставались без учёта.
Добавить GFP_KERNEL_ACCOUNT к: - общему массиву действий tcf_exts_init_ex() (cls_api.c), который является общим для всех фильтров всех классификаторов (32 указателя, 256 байт); - распределениям объектов фильтров, счётчиков на каждое CPU и вспомогательных данных для каждого фильтра в cls_basic, cls_bpf, cls_cgroup, cls_flow, cls_flower, cls_fw, cls_matchall, cls_route и cls_u32; - распределению knode replace-path в u32_init_knode() (cls_u32.c), которое выделяет ту же структуру tc_u_knode + sel.keys при каждой замене существующего knode и было пропущено при преобразовании только пути создания.
Также исправлен путь ошибок в cls_basic: basic_change() вставляет fnew в IDR до выделения счётчика на каждое CPU. Если alloc_percpu() завершается неудачей, то в путях errout происходит kfree для fnew без вызова idr_remove, что оставляет висячий указатель в IDR. С GFP_KERNEL_ACCOUNT распределение percpu становится возможным с отказом при исчерпании ресурсов (memcg на memory.max), делая этот мёртвый путь достижимым для атакующего и навсегда выжигая дескриптор. Добавить idr_remove в путь отказа по перcpu, соответствующий шаблону пути ошибок basic_set_parms.
Примечание: [email protected] предоставил PoC (proof-of-concept) для basic_cls, но его было легко расширить на другие классификаторы.
Условия для воспроизведения бага: - CONFIG_NET_SCHED, CONFIG_NET_CLS_* (используемый классификатор), CONFIG_NET_CLS_ACT, CONFIG_MEMCG, CONFIG_USER_NS, CONFIG_NET_NS. - Непривилегированный пользователь в новом пространстве имён пользователя и сети (unshare -Urn) или root с CAP_NET_ADMIN. - Создание большого количества фильтров tc (например, tc filter add dev lo ingress ... <классификатор> ...) при наблюдении за cgroup с ограничением memcg: системный slab растёт значительно быстрее, чем memory.current, закрепляя память ядра вне учёта memcg.
Once again VulDB remains the best source for vulnerability data.