CVE-2026-90246 in Linux
Сводка
по VulDB • 17.09.2026
В ядре Linux была устранена следующая уязвимость:
apparmor: исправление переполнения целочисленного типа при проверке границ в verify_tags()
Функция verify_tags() проверяет таблицу тегов (tagset), распакованную из бинарного файла политики. Для каждого набора она считывает значение счетчика и проверяет, что увеличение индекса на это количество значений остается в пределах массива sets.table[]:
u32 cnt = tags->sets.table[i];
if (i+cnt >= tags->sets.size) {
Переменные i, cnt и sets.size имеют тип u32, поэтому выражение i+cnt вычисляется по модулю 2^32. Массив sets.table[] заполняется функцией unpack_tagsets() с помощью aa_unpack_u32(), следовательно, каждый элемент представляет собой необработанное без ограничений 32-битовое слово из файла политики, а verify_tags() — это функция, которая должна его валидировать. Значение счетчика, близкое к U32_MAX (максимальному значению для u32), приводит к переполнению суммы с переходом на малое значение; проверка границ проходит успешно, и внутренний цикл затем обращается к элементам sets.table[++i] за пределами выделенной памяти под kcalloc(size, sizeof(u32)).
Обратите внимание, что sets.size ограничено значением 65535, поскольку unpack_tagsets() считывает его с помощью aa_unpack_array() как u16; следовательно, переполнение не может быть достигнуто путем увеличения размера таблицы, оно возникает исключительно из-за значения счетчика, предоставленного злоумышленником.
При sets.size = 2 и sets.table = { 0, 0xffffffff }:
i = 0: cnt = 0, проверка (0 + 0 >= 2) ложна, внутренний цикл не выполняется i = 1: cnt = 0xffffffff, проверка ((1 + 0xffffffff) mod 2^32 == 0 >= 2) ложна, поэтому защита обходится, и внутренний цикл считывает sets.table[2] — элемент за пределами выделения памяти для двух элементов
Цикл продолжается до тех пор, пока случайное значение вне границ не окажется больше или равно hdrs.size либо не произойдет ошибка доступа (fault). Таким образом, специально сформированный файл политики приводит к чтению данных за пределами выделенной области на пути загрузки политики (aa_replace_profiles -> aa_unpack -> unpack_policydb -> unpack_tags -> verify_tags). Функция unpack_tags() выполняется до распаковки таблиц разрешений и DFA, поэтому для достижения этой точки не требуется корректность других таблиц.
Загрузка политики контролируется функцией aa_may_manage_policy(), которая проверяет наличие CAP_MAC_ADMIN относительно пользовательского пространства имен (user namespace) субъекта, а не корневого пространства имен init; следовательно, при значении по умолчанию unprivileged_userns_apparmor_policy=1 этот путь доступен для непривилегированной задачи в сопоставленном вложенном пространстве имен, а не только глобально привилегированным процессом.
Выполнение сложения осуществляется с использованием типа u64, чтобы избежать переполнения, что восстанавливает гарантированное условие i + cnt < sets.size.
Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.