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

Сводка

по VulDB • 22.08.2026

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

mm/huge_memory: исправление гонки данных (race condition) в huge_zero_pfn

Серия патчей "mm/huge_memory: fix huge_zero_pfn race", версия 2.

Существует тонкая гонка данных в реализации huge_zero_folio с подсчетом ссылок.

Атомарная логика быстрого пути не учитывает тот факт, что shrinker (который сбрасывает последнее закрепление счетчика huge_zero_refcount) может перезаписать значение huge_zero_pfn на sentinel-значение ~0UL в функции shrink_huge_zero_folio_scan() после того, как конкурентный вызов get_huge_zero_folio() установил там корректное значение.

Это приводит к тому, что huge_zero_folio устанавливается правильно, но huge_zero_pfn — неверно, вследствие чего is_huge_zero_pfn(), а следовательно, и is_huge_zero_pmd() ошибочно идентифицируют огромный нулевой folio как обычный THP-folio (Transparent Huge Page).

Это может привести к некорректному разделению огромного нулевого folio и его неправильной обработке.

Решение этой проблемы очень тонкое, так как существует атомарный быстрый путь, поэтому порядок операций на архитектурах со слабой упорядоченностью (weakly ordered architectures) должен обрабатываться с особой тщательностью.

Первый коммит исправляет проблему путем введения спинлока вокруг записи в huge_zero_[pfn, folio, refcount], при этом особое внимание уделяется порядку операций загрузки/записи на быстром пути. Он размещен первым и оставлен максимально компактным, чтобы его можно было бэкпортировать отдельно.

Второй коммит является чистой очисткой кода (cleanup) и перерабатывает логику CONFIG_PERSISTENT_HUGE_ZERO_FOLIO для более четкого разделения постоянной логики от динамически выделяемой.


Этот патч (из 2):

Если !CONFIG_PERSISTENT_HUGE_ZERO_FOLIO, то huge_zero_folio имеет подсчет ссылок через huge_zero_refcount и возвращается функцией mm_get_huge_zero_folio().

Когда вызывающая сторона завершает работу со страницей огромного нуля, ее счетчик ссылок уменьшается. Только shrinker может установить счетчик ссылок в ноль.

К сожалению, может возникнуть гонка данных между уменьшением счетчика ссылок до нуля функцией shrinker и одновременным исключением страницы (page fault).

Это происходит потому, что shrink_huge_zero_folio_scan() может, при очень неудачном стечении обстоятельств, быть прерван после установки huge_zero_refcount в ноль, но перед записью некорректного значения.

В течение этого времени get_huge_zero_folio() может записать значение в huge_zero_pfn до того, как shrink_huge_zero_folio_scan() возобновит выполнение.

В этом случае огромный нулевой folio будет постоянно ошибочно идентифицирован, что приведет к некорректному переходу кодового пути THP для огромного нулевого folio:

CPU 0 CPU 1 =======================================|================================= shrink_huge_zero_folio_scan() | atomic_cmpxchg() устанавливает refcount в 0 | xchg() устанавливает huge_zero_folio в NULL | get_huge_zero_folio() | | atomic_inc_not_zero() -> ноль прерван на долгое время | Выделение нового огромного нулевого folio | | Запись корректного huge_zero_folio v | Запись корректного huge_zero_pfn Перезапись huge_zero_pfn значением ~0UL <--- Некорректная перезапись!

Это приводит к тому, что is_huge_zero_pfn() и is_huge_zero_pmd() ошибочно возвращают false для страницы огромного нуля, что может вызвать проблемы, такие как некорректное разделение огромного нулевого folio.

Обратите внимание, что проблема касается huge_zero_pfn, а не huge_zero_folio, поскольку get_huge_zero_folio() использует cmpxchg(), заблокированный на условии, что huge_zero_folio равен NULL, с циклом повторных попыток (retry loop), а shrink_huge_zero_folio_scan() использует xchg() для установки huge_zero_folio.

Исправьте проблему путем введения спинлока huge_zero_lock для предотвращения конкурентной записи в huge_zero_folio, huge_zero_pfn и huge_zero_refcount.

Здесь необходимо проявить значительную осторожность для обеспечения корректности:

Быстрый путь в get_huge_zero_folio() использует atomic_inc_not_zero(), который находится вне критической секции, и означает, что выделение огромного нуля заблокировано на условии нулевого значения huge_zero_refcount.

Быстрый путь не использует huge_zero_lock, поэтому критическая секция для него нерелевантна.

Таким образом, требуются инварианты — huge_zero_refcount ДОЛЖЕН:

* Устанавливаться только в критической секции huge_zero_lock для обеспечения сериализации huge_zero_pfn, huge_zero_folio и ---обрезано---

If you want to get best quality of vulnerability data, you may have to visit VulDB.

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

Linux

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

15.08.2026

Раскрытие

22.08.2026

Модерация

принято

Вход

VDB-394406

EPSS

0.00000

KEV

Нет

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

Очень низкий

Источники

Do you need the next level of professionalism?

Upgrade your account now!