Ad

CVE-2026-89544

HIGH CVSS 3.1: 7,5 EPSS 0.59%
Обновлено 21 сентября 2026
Linux
Параметр Значение
CVSS 7,5 (HIGH)
Поставщик Linux
Публичный эксплойт Нет

В ядре Linux устранена следующая уязвимость: SUNRPC: исправлены ошибки пути gssx_dec_option_array. Четыре связанных дефекта в декодере с дополнительным массивом gssx XDR делают пути ошибок небезопасны: разыменование NULL в вызывающем объекте, утечка счетчика ссылок декодированная информация group_info и скрытое использование после освобождения, которое привело к утечке в противном случае исправление будет раскрыто. gssx_dec_option_array() устанавливает oa->count = 1 перед выделением оа->данные. Если это распределение не удалось, возвращается -ENOMEM с oa->count == 1 и oa->data == NULL.

Все остальные пути ошибок перескакивают на free_oa: который освобождает oa->данные и обнуляет их, но также оставляет oa->count == 1. Вызывающая сторона доверяет счетчику: 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: так что счетчик и данные останутся. когерентен, и вызывающая сторона видит пустой массив опций. - Вызовите 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 прописаны и всё else равно нулю из kzalloc. - В gssx_dec_linux_creds() out_free_groups: путь, выпуск cr_group_info с помощью put_group_info() вместо groups_free() поэтому демонтаж соответствует пути free_svc_cred(), учитывающему количество ссылок, и очистите указатель, чтобы позже вызвать free_svc_cred() на том же самом creds не выпускает его во второй раз.

Показать оригинальное описание (EN)

In the Linux kernel, the following vulnerability has been resolved: SUNRPC: fix gssx_dec_option_array error path bugs Four coupled defects in the gssx XDR option-array decoder make the error paths unsafe: a NULL deref in the caller, a refcount leak on the decoded group_info, and a latent use-after-free that the leak fix would otherwise expose. gssx_dec_option_array() sets oa->count = 1 before allocating oa->data. If that allocation fails, -ENOMEM is returned with oa->count == 1 and oa->data == NULL. All other error paths jump to free_oa: which frees oa->data and NULLs it but also leaves oa->count == 1. The caller trusts the count: gssp_accept_sec_context_upcall() gssx_dec_accept_sec_context() gssx_dec_option_array() /* fails, count=1 data=NULL */ data = res.options.data[0].value /* NULL deref */ Independently, free_creds: releases the partially decoded svc_cred with a bare kfree(creds). gssx_dec_linux_creds() installs a groups_alloc() result into creds->cr_group_info; that object is kvmalloc-backed and refcounted, and only put_group_info() reaches kvfree(). A plain kfree(creds) drops the wrapper and leaks the group_info allocation. The natural fix for the leak is to call free_svc_cred(creds) before kfree(creds), but free_svc_cred() invokes put_group_info() on creds->cr_group_info unconditionally when non-NULL. The existing out_free_groups: path in gssx_dec_linux_creds() already called groups_free() on that pointer without clearing it, so once free_svc_cred() is wired in, the subsequent put_group_info() would touch freed memory. Fix all four together: - Move the oa->count = 1 assignment below the oa->data allocation so it is never set when oa->data is NULL. - Reset oa->count to 0 at free_oa: so count and data stay coherent and the caller sees an empty option array. - Call free_svc_cred(creds) before kfree(creds) at free_creds: so the refcounted cr_group_info is released. free_svc_cred() either NULL-guards each field explicitly (cr_group_info has an if() check) or delegates to a helper that is NULL-safe itself (kfree for the string fields, gss_mech_put() which guards with if(gm) at gss_mech_switch.c:342), so it is safe to call on a partially decoded svc_cred where only cr_uid/cr_gid/cr_group_info have been written and everything else is zero from kzalloc. - In gssx_dec_linux_creds()'s out_free_groups: path, release cr_group_info with put_group_info() rather than groups_free() so the teardown matches free_svc_cred()'s refcount-aware path, and clear the pointer so a later free_svc_cred() on the same creds does not release it a second time.

Характеристики атаки

Способ атаки
По сети
Атака возможна удалённо
Сложность
Низкая
Легко эксплуатировать
Нужны права
Не требуются
Права не нужны
Участие пользователя
Не требуется
Не нужно действие пользователя

Последствия

Конфиденциальность
Нет
Нет утечки данных
Целостность
Нет
Нет модификации данных
Доступность
Высокое
Полный отказ в обслуживании

Строка CVSS v3.1