В ядре Linux устранена следующая уязвимость:
NFS: исправлена утечка Delegation_hash_table при сбое nfs4_server_common_setup()
nfs4_server_common_setup() выделяет сервер->delegation_hash_table
сначала, но server->destroy - единственный путь, который освобождает таблицу через
nfs4_destroy_server() — не назначается до самого конца
функция. Если какой-либо промежуточный шаг завершается неудачей (is_ds_only_client()
проверьте, nfs4_init_session(), nfs4_get_rootfh() или nfs_probe_server()),
функция возвращает значение server->destroy по-прежнему NULL, поэтому вызывающая сторона
nfs_free_server() пропускает обратный вызов уничтожения, и хэш-таблица
утечка (4 КиБ за попытку с водяным знаком делегирования по умолчанию). Это тривиально доступно из пользовательского пространства: каждое неудачное монтирование NFSv4
утечка одного выделения.
Клиент, который постоянно пытается выполнить монтирование,
не может добиться успеха, утечка памяти ядра без ограничений. Наблюдается в
производство, где средство опроса резервных копий Longhorn повторило попытку mount.nfs4
сервер только с NFSv3 примерно 10 раз в секунду, утечка ~3,4 ГиБ
неутилизируемая плита (kmalloc-rnd-13-4k) в сутки; узел накопился
12 ГиБ вытекшей плиты до того, как источник был идентифицирован с помощью
kmem: точка трассировки kmalloc (call_site=nfs4_delegation_hash_alloc). Репродуктор:
# сервер экспортирует только NFSv3 (или путь экспорта отсутствует для v4)
пока :; do mount -t nfs4 <сервер>:/missing/mnt; сделано
# наблюдаем, как SUnreclaim в /proc/meminfo растет на 4 КиБ за итерацию
Освободите таблицу на путях ошибок между выделением и
назначение сервера->уничтожить.
Показать оригинальное описание (EN)
In the Linux kernel, the following vulnerability has been resolved: NFS: fix delegation_hash_table leak when nfs4_server_common_setup() fails nfs4_server_common_setup() allocates server->delegation_hash_table first, but server->destroy - the only path that frees the table via nfs4_destroy_server() - is not assigned until the very end of the function. If any intermediate step fails (the is_ds_only_client() check, nfs4_init_session(), nfs4_get_rootfh(), or nfs_probe_server()), the function returns with server->destroy still NULL, so the caller's nfs_free_server() skips the destroy callback and the hash table is leaked (4 KiB per attempt with the default delegation watermark). This is trivially reachable from userspace: every failed NFSv4 mount leaks one allocation. A client that persistently retries a mount that cannot succeed leaks kernel memory without bound. Observed in production where a Longhorn backup poller retried mount.nfs4 against an NFSv3-only server roughly 10 times per second, leaking ~3.4 GiB of unreclaimable slab (kmalloc-rnd-13-4k) per day; the node accumulated 12 GiB of leaked slab before the source was identified via the kmem:kmalloc tracepoint (call_site=nfs4_delegation_hash_alloc). Reproducer: # server exports NFSv3 only (or export path absent for v4) while :; do mount -t nfs4 <server>:/missing /mnt; done # watch SUnreclaim in /proc/meminfo grow 4 KiB per iteration Free the table on the error paths between the allocation and the assignment of server->destroy.