flawopen.com/Teardowns/cve-2024-1086-linux-netfilter-nftables-uaf
CVE-2024-1086: use-after-free в Linux nf_tables
CVE-2024-1086 — use-after-free в Linux nf_tables из-за принятия неверных параметров DROP. Установите исправленное ядро из вашей дистрибуции.
Представьте форму, где сотрудник может выбрать только «принять» или «отбросить». В отдельном поле указывается код ошибки для отказа: там допустимы ноль или корректная отрицательная ошибка. Уязвимая проверка пропускала положительное значение «принять» в это поле. Позже сетевой код трактовал вердикт непоследовательно. Исправление закрывает этот путь и принимает только точные поддерживаемые значения.
Ключевые понятия и термины
nf_tables- Подсистема ядра Linux, которую nftables использует для настройки фильтрации пакетов и связанных сетевых правил.
Вердикт Netfilter- Результат обработки правила пакета в ядре, например
NF_ACCEPTилиNF_DROP. Для DROP hook ожидает ноль или корректный отрицательный errno. Use-after-free (CWE-416)- Ошибка памяти, при которой код обращается к объекту после завершения его срока жизни. NVD указывает здесь локальное повышение привилегий в ядре.
User namespace- Пространство имён Linux, сопоставляющее идентификаторы и полномочия процессов. Возможность его создания без привилегий зависит от политики ядра и дистрибутива; сама по себе она не означает выход на хост.
Связи со стандартами
- Ссылка CWE для слабого места, описанного в этом руководстве: CWE-416
- CISA KEV — добавлено 2024-05-30 — CVE-2024-1086
Анализ первопричины
В net/netfilter/nf_tables_api.c функция nft_verdict_init() раньше маскировала значение вердикта и принимала параметры для NF_DROP или NF_QUEUE. Хук Netfilter ожидает в старших битах NF_DROP ноль или корректный отрицательный errno. Согласно upstream-исправлению, положительное значение, например NF_ACCEPT, могло привести к use-after-free. Патч удаляет разрешающий путь и принимает только точные поддерживаемые вердикты; остальные значения возвращают -EINVAL. NVD указывает на локальное повышение привилегий. Возможность атаки зависит от ядра, доступных полномочий и политики дистрибутива; не следует считать все контейнеры одинаково уязвимыми.
Пошаговый сценарий атаки
Локальная возможность управлять правилами
Описанная атака локальная. Процесс должен иметь доступ к проверке вердиктов nf_tables; необходимые полномочия и доступность непривилегированных user namespace зависят от настроек хоста.
Неверный параметр вердикта проходит проверку
До исправления nft_verdict_init() принимала некоторые значения после применения NF_VERDICT_MASK, включая положительное NF_ACCEPT в битах параметра.
Хук доходит до use-after-free
Хук Netfilter трактует параметры NF_DROP как ноль или допустимый отрицательный errno. В upstream-отчёте сказано, что принятый положительный параметр может вызвать use-after-free при обработке пакета; патч не подтверждает универсальную примитиву эксплуатации или гарантированный выход из контейнера.
Установите исправленное ядро дистрибутива
Upstream-изменение отклоняет неподдерживаемые параметры вердикта. Установите и загрузите исправленное ядро, предоставленное дистрибутивом: версии пакетов и переносы исправления различаются.
Исходный код: Уязвимый vs Защищённый вариант
Уязвимый код маскировал вердикт и переходил к дальнейшей обработке, поэтому параметр вроде положительного NF_ACCEPT мог попасть в поле ошибки NF_DROP. Исправление допускает только точные константы и возвращает -EINVAL для остальных значений. Это целевые фрагменты upstream-патча, а не автономные компилируемые функции.
Фрагмент исходного кода: net/netfilter/nf_tables_api.c
/* Фрагмент nft_verdict_init() в net/netfilter/nf_tables_api.c до f342de4e2f33.
* Путь с маскированным значением принимал параметризованные вердикты. */
switch (data->verdict.code) {
default:
switch (data->verdict.code & NF_VERDICT_MASK) {
case NF_ACCEPT:
case NF_DROP:
case NF_QUEUE:
break;
default:
return -EINVAL;
}
fallthrough;
case NFT_CONTINUE:
case NFT_BREAK:
case NFT_RETURN:
/* Далее следует обработка остальных существующих вердиктов. */
break;
}
/* Фрагмент nft_verdict_init() в net/netfilter/nf_tables_api.c,
* изменённый в f342de4e2f33. */
switch (data->verdict.code) {
case NF_ACCEPT:
case NF_DROP:
case NF_QUEUE:
break;
case NFT_CONTINUE:
case NFT_BREAK:
case NFT_RETURN:
/* Далее следует обработка остальных существующих вердиктов. */
break;
default:
return -EINVAL;
}
Чек-лист по защите системы для инженеров
- ✓Установите и загрузите исправленный пакет ядра, рекомендованный дистрибутивом; после перезагрузки проверьте запущенное ядро, поскольку исправления переносятся в разные версии.
- ✓Сверьтесь с бюллетенем безопасности дистрибутива для точной разновидности ядра и пакета, а не только с номером upstream-версии.
- ✓Если обновление откладывается, оцените документированный поставщиком способ ограничить создание непривилегированных user namespace; проверьте наличие настройки и влияние на контейнеры и настольные приложения.
- ✓При проверке валидации вердиктов ядра отклоняйте неподдерживаемые биты параметров до попадания в путь сетевого hook и тестируйте точные допустимые константы и неверные положительные значения.