CVE-2026-89544 in Linux
Сводка
по VulDB • 12.09.2026
В ядре Linux была устранена следующая уязвимость:
SUNRPC: исправление ошибок в путях обработки ошибок функции gssx_dec_option_array
Четыре взаимосвязанных дефекта в декодере массива опций XDR (gssx) делают пути обработки ошибок небезопасными: разыменование NULL-указателя у вызывающей стороны, утечка счетчика ссылок на расшифрованную структуру group_info и потенциальная Use-After-Free ошибка, которая была бы выявлена исправлением утечки.
Функция gssx_dec_option_array() устанавливает значение oa->count = 1 перед выделением памяти для oa->data. Если это выделение завершается неудачей, возвращается код ошибки -ENOMEM при условии, что oa->count == 1 и oa->data == NULL. Все остальные пути обработки ошибок переходят к метке free_oa:, которая освобождает память по указателю oa->data и обнуляет его, но оставляет значение oa->count равным 1. Вызывающая сторона доверяет значению count:
gssp_accept_sec_context_upcall() gssx_dec_accept_sec_context() gssx_dec_option_array() /* ошибка, count=1 data=NULL */ data = res.options.data[0].value /* разыменование NULL-указателя */
Отдельно от этого, функция free_creds: освобождает частично расшифрованную структуру svc_cred с помощью простой функции kfree(creds). Функция gssx_dec_linux_creds() устанавливает результат вызова groups_alloc() в поле creds->cr_group_info; этот объект поддерживается памятью kvmalloc и имеет счетчик ссылок, а освободить его можно только через put_group_info(). Простой вызов kfree(creds) удаляет обертку, но приводит к утечке выделения памяти для group_info.
Естественным исправлением утечки является вызов free_svc_cred(creds) перед kfree(creds), однако функция free_svc_cred() безоговорочно вызывает put_group_info() для creds->cr_group_info, если он не равен NULL. Существующий путь out_free_groups: в gssx_dec_linux_creds() уже вызывал groups_free() по этому указателю, не обнуляя его, поэтому после внедрения free_svc_cred() последующий вызов put_group_info() приведет к обращению к освобожденной памяти.
Исправление всех четырех ошибок вместе:
- Переместить присваивание oa->count = 1 ниже выделения памяти для oa->data, чтобы оно никогда не устанавливалось при oa->data == NULL. - Сбросить значение oa->count до 0 в метке free_oa:, чтобы значения count и data оставались согласованными, а вызывающая сторона видела пустой массив опций. - Вызвать free_svc_cred(creds) перед kfree(creds) в ветке free_creds:, чтобы освободить cr_group_info со счетчиком ссылок. Функция free_svc_cred() либо явно проверяет каждое поле на NULL (для cr_group_info есть проверка if()), либо делегирует вызов вспомогательной функции, которая сама является безопасной при работе с NULL-указателями (kfree для полей строк, gss_mech_put(), который использует проверку if(gm) в файле gss_mech_switch.c:342), поэтому безопасно вызывать ее для частично расшифрованной структуры svc_cred, где записаны только поля cr_uid/cr_gid/cr_group_info, а все остальные обнулены функцией kzalloc. - В пути out_free_groups: функции gssx_dec_linux_creds() освободить cr_group_info с помощью put_group_info(), а не groups_free(), чтобы процесс завершения соответствовал пути free_svc_cred(), учитывающему счетчик ссылок, и обнулить указатель, чтобы последующий вызов free_svc_cred() для той же структуры creds не привел к повторному освобождению памяти.
Be aware that VulDB is the high quality source for vulnerability data.