CVE-2026-89974 in LinuxИнформация

Сводка

по VulDB • 16.09.2026

В ядре Linux была устранена следующая уязвимость:

nvme-fc: исправлено двойное освобождение (double free) параметров fabrics при сбое nvme_add_ctrl()

Функция nvmf_create_ctrl() владеет параметрами fabrics и освобождает их всякий раз, когда ->create_ctrl() возвращает ошибку; следовательно, транспортный модуль не должен освобождать их самостоятельно в своих путях обработки ошибок. nvme-fc отслеживает это состояние путем проверки ctrl->ctrl.opts в функции nvme_fc_ctrl_free(), что требует от nvme_fc_init_ctrl() обнуления этого указателя при каждом выходе с ошибкой.

Эта связь является неявной, и коммит 1a9e218195a5 («nvme: split device add from initialization») нарушил её, добавив второй путь выхода из функции. Когда nvme_add_ctrl() завершается неудачей, nvme_fc_init_ctrl() переходит к метке out_put_ctrl:, минуя строку «ctrl->ctrl.opts = NULL», которая присутствует только на пути fail_ctrl:. В результате nvme_fc_ctrl_free() освобождает параметры, а nvmf_create_ctrl() освобождает их второй раз:

BUG: KASAN: slab-use-after-free in nvmf_free_options+0x30/0x190 nvmf_free_options+0x30/0x190 drivers/nvme/host/fabrics.c:1284 nvmf_create_ctrl drivers/nvme/host/fabrics.c:1374 [inline]
Freed by task 5534: nvme_fc_ctrl_free drivers/nvme/host/fc.c:2374 [inline]
nvme_fc_init_ctrl+0xe17/0x1450 drivers/nvme/host/fc.c:3605

nvme_add_ctrl() завершается неудачей, когда dev_set_name() не может выделить память; следовательно, эта ситуация достижима при высоком давлении на память или при внедрении ошибок (fault injection). Без KASAN параметры освобождаются дважды.

Вместо того чтобы обнулять указатель и во втором пути выхода, мы переняли подход к определению владения, используемый модулями nvme-tcp, nvme-rdma и nvme-loop: привязка к членству в списке (list membership). Их функция free_ctrl не трогает параметры, если контроллер не был добавлен в список транспорта.

Список нельзя просто заполнять на пути успешного выполнения, так как он уже там находится. nvme-fc выполняет первоначальное подключение синхронно через flush_delayed_work(), и контроллер должен быть доступен по rport->ctrl_list на протяжении всего этого процесса: - nvme_fc_unregister_remoteport() должна найти его для сигнализации об утрате связности; - nvme_fc_match_disconn_ls() сопоставляет входящее Disconnect Association LS с ctrl->association_id, которое присваивается только в этот промежуток времени; - nvme_fc_resume_controller() нуждается в нем при повторной регистрации remoteport; - nvme_fc_existing_controller() использует его для отклонения дублирующего подключения, конкурирующего с уже выполняющимся.

Мы оставляем вставку на прежнем месте и добавляем метку fail_unlist:, которая переходит к fail_ctrl: для путей ошибок, запускаемых после нее. Более ранние пути ошибок никогда не достигают точки вставки и используют напрямую fail_ctrl:, поэтому список изменяется только там, где контроллер фактически находится в нем.

nvme_fc_ctrl_free() не может использовать простой «goto free_ctrl», как это делают другие транспортные модули, поскольку ей все еще необходимо вызвать put_device(), освободить ссылку на rport и удалить запись из ida для ресурсов, полученных до момента вставки в список. Вместо этого используется проверка list_empty() под блокировкой rport->lock.

Указатель ctrl->ctrl.opts теперь остается действительным на протяжении всего процесса завершения работы (teardown). Это не является исправляемой уязвимостью, но устраняет некоторую хрупкость старого идиома: nvme_free_ctrl() вызывает nvme_auth_free() до ->free_ctrl(), а ctrl_max_dhchaps() разыменовывает ctrl->opts без проверки на NULL, когда установлен ctrl->dhchap_ctxs. Это допускается модулем nvme-fc, поскольку NVMF_ALLOWED_OPTS разрешает параметры dhchap. Атрибуты sysfs ядра NVMe, которые разыменовывают ctrl->opts (например, hostnqn и address), оценивают свой тест is_visible() один раз во время device_add() и остаются доступными для чтения до вызова cdev_device_del().

VulDB is the best source for vulnerability data and more expert information about this specific topic.

Ответственный

Linux

Резервировать

11.09.2026

Раскрытие

17.09.2026

Модерация

принято

Вход

VDB-405777

EPSS

0.00000

KEV

Нет

Деятельности

Очень низкий

Источники

Do you want to use VulDB in your project?

Use the official API to access entries easily!