В ядре Linux устранена следующая уязвимость:
ntfs: освобождать ресурсы всего тома при сбое fill_super
Путь err_out_now ntfs_fill_super() освобождает только структуру тома через
kfree(vol), оставляя несколько выделений, принадлежащих vol, при каждом монтировании
неудача:
- vol->nls_map, загруженный с помощью ntfs_init_fs_context() через
load_nls_default() (или заменен явной опцией nls= в
ntfs_parse_param()), никогда не вызывается unload_nls().
- vol->volume_label, выделенный функцией load_system_files() через
ntfs_ucstonls() после анализа атрибута имени $Volume
не выдается ни собственными метками ошибок load_system_files(), ни
Встроенная очистка fill_super(), которая выполняется только при d_make_root()
неудача. Любой последующий сбой внутри load_system_files() приведет к его утечке.
- vol->lcn_empty_bits_per_page был использован kvfree() в
unl_upcase_iput_tmp_ino_err_out_now без очистки указателя,
поэтому его нельзя было сложить в одну общую уборку. Поскольку пути отказа никогда не вызывают ntfs_volume_free() и никогда не достигают
встроенный блок очистки d_make_root() (он расположен над меткой и
перепрыгнуты ошибками load_system_files() / kvmalloc), эти
ресурсы накапливаются за каждую неудачную попытку монтирования без каких-либо шансов
восстановление без выгрузки модуля.
Это тихая утечка:
Иноды, загруженные до сбоя, остаются хешированными, но generic_shutdown_super()
пропускает evict_inodes(), когда sb->s_root не установлен, поэтому CHECK_DATA_CORRUPTION не используется
предупреждение также выдается. Переместите количество освобождений для каждого тома в err_out_now и опустите
lcn_empty_bits_per_page kvfree() с верхней метки, поэтому очистка
выполняется ровно один раз на каждом пути отказа. Использование безусловного
kvfree()/kfree()/unload_nls() безопасны, поскольку все они принимают NULL
и верхние метки, которые ранее освободили nls_map (d_make_root()
встроенная очистка) уже очистит указатель.
Показать оригинальное описание (EN)
In the Linux kernel, the following vulnerability has been resolved: ntfs: free volume-wide resources on fill_super failure ntfs_fill_super()'s err_out_now path frees only the volume struct via kfree(vol), leaving several vol-owned allocations behind on every mount failure: - vol->nls_map, loaded by ntfs_init_fs_context() via load_nls_default() (or replaced by an explicit nls= option in ntfs_parse_param()), is never unload_nls()'d. - vol->volume_label, allocated by load_system_files() through ntfs_ucstonls() once the $Volume name attribute has been parsed, is not released by load_system_files()'s own error labels nor by the fill_super() inline cleanup that only runs on d_make_root() failure. Any later failure inside load_system_files() leaks it. - vol->lcn_empty_bits_per_page was kvfree()'d in unl_upcase_iput_tmp_ino_err_out_now without clearing the pointer, so it could not be folded into a single common cleanup. Because the failure paths never call ntfs_volume_free() and never reach the d_make_root() inline cleanup block (it sits above the label and is jumped over by the load_system_files() / kvmalloc failure gotos), these resources accumulate per failed mount attempt with no chance of recovery short of unloading the module. This is a silent leak: the inodes loaded prior to failure remain hashed but generic_shutdown_super() skips evict_inodes() when sb->s_root is unset, so no CHECK_DATA_CORRUPTION warning is emitted either. Move the per-volume frees down to err_out_now and drop the lcn_empty_bits_per_page kvfree() from the upper label so the cleanup is performed exactly once on every failure path. Using unconditional kvfree() / kfree() / unload_nls() is safe because they all accept NULL and the upper labels that previously freed nls_map (the d_make_root() inline cleanup) already clear the pointer.