В ядре Linux устранена следующая уязвимость:
fs/proc/task_mmu: исправить гонку make_uffd_wp_huge_pte() prot-update
Серия патчей «userfaultfd/pagemap: существующие исправления». Это уже существующие исправления ошибок, которые были внесены в начало статьи.
userfaultfd Серия отслеживания рабочих наборов RWP до версии 5 [1]. За отзыв
отзывы о том, что исправления не должны находиться в середине серии функций, они
разделяются и отправляются самостоятельно; серия RWP перепостена на основе
вершина этого.
Все шесть были отмечены обзором Sashiko AI серии RWP и содержат
независимо от RWP, обратитесь непосредственно к mm-new и укажите Cc: стабильный@.
1: fs/proc/task_mmu: отсутствует огромных_ptep_modify_prot_start() в
make_uffd_wp_huge_pte() может потерять аппаратные обновления. Грязные/доступные обновления
когда PAGEMAP_SCAN защищает от записи огромный PTE.
2: fs/proc/task_mmu: pagemap_scan_hugetlb_entry() сравнивает диапазон
относительно HPAGE_SIZE, а не размера страницы hstate, поэтому он никогда не
защищает от записи гигантские страницы огромных размеров.
3: fs/proc/task_mmu: PAGEMAP_SCAN с PM_SCAN_WP_MATCHING по
самоблокировки незаполненного диапазона огромных tlb -- pagemap_scan_pte_hole()
вызывает uffd_wp_range(), в то время как walk_hugetlb_range() содержит огромный tlb
vma блокирует чтение, а затем огромных tlb_change_protection() принимает его
для записи. Вместо этого установите встроенный маркер.
4: mm/huge_memory: Change_non_present_huge_pmd() удаляет pmd_swp_uffd_wp
при понижении разрешения PMD для частного устройства, молча теряя
маркер uffd-wp.
5: userfaultfd: must_wait() применяет pte_write() к чтению без блокировки
PTE без проверки pte_present(), поэтому записи обмена/миграции
декодируйте случайные биты смещения, и поток может оставаться припаркованным на устаревшем
вина.
6: userfaultfd: __VMA_UFFD_FLAGS передает VMA_UFFD_MINOR_BIT (41) в
mk_vma_flags() безусловно, запись за пределами границ в
одно слово vma_flags_t в 32-битной версии.
Создайте маску из config-gated
маски для каждого режима, поэтому недоступный бит никогда не материализуется. Этот патч (из 6):
make_uffd_wp_huge_pte() активирует бит UFFD_WP на текущем HugeTLB PTE путем
вызов Huge_ptep_modify_prot_commit() со снимком ptent, который был
извлекается без соответствующего огромных_ptep_modify_prot_start().
start helper — это то, что атомарно очищает запись, поэтому принадлежащий ядру
снимок остается последовательным до момента фиксации; без него оборудование может
установите Dirty или Accessed в реальном PTE между исходным чтением и
commit и Huge_ptep_modify_prot_commit() (чья общая реализация
просто вызывает set_huge_pte_at()), а затем записывает устаревший снимок обратно в
живые аппаратные биты, потеря обновления. Брат make_uffd_wp_pte(), не относящийся к Hugetlb, делает это правильно через
ptep_modify_prot_start() / ptep_modify_prot_commit().
Зеркально отразите этот шаблон по настоящему - ветка ПТЭ. Ситуация с миграцией остается прежней – миграция записи отсутствуют, поэтому нет обновления оборудования, с которым можно было бы соревноваться.
Показать оригинальное описание (EN)
In the Linux kernel, the following vulnerability has been resolved: fs/proc/task_mmu: fix make_uffd_wp_huge_pte() prot-update race Patch series "userfaultfd/pagemap: pre-existing fixes". These are pre-existing bug fixes that were carried at the front of the userfaultfd RWP working-set-tracking series up to v5 [1]. Per review feedback that fixes should not sit in the middle of a feature series, they are split out and sent on their own; the RWP series is reposted rebased on top of this. All six were flagged by the Sashiko AI review of the RWP series and carry independent of RWP, apply to mm-new directly, and carry Cc: stable@. 1: fs/proc/task_mmu: a missing huge_ptep_modify_prot_start() in make_uffd_wp_huge_pte() can lose hardware Dirty/Accessed updates when PAGEMAP_SCAN write-protects a hugetlb PTE. 2: fs/proc/task_mmu: pagemap_scan_hugetlb_entry() compares the range against HPAGE_SIZE rather than the hstate page size, so it never write-protects gigantic hugetlb pages. 3: fs/proc/task_mmu: PAGEMAP_SCAN with PM_SCAN_WP_MATCHING over an unpopulated hugetlb range self-deadlocks -- pagemap_scan_pte_hole() calls uffd_wp_range() while walk_hugetlb_range() holds the hugetlb vma lock for read, and hugetlb_change_protection() then takes it for write. Install the marker inline instead. 4: mm/huge_memory: change_non_present_huge_pmd() drops pmd_swp_uffd_wp on a device-private PMD permission downgrade, silently losing the uffd-wp marker. 5: userfaultfd: must_wait() applies pte_write() to a locklessly read PTE without checking pte_present(), so swap/migration entries decode random offset bits and a thread can stay parked on a stale fault. 6: userfaultfd: __VMA_UFFD_FLAGS feeds VMA_UFFD_MINOR_BIT (41) to mk_vma_flags() unconditionally, an out-of-bounds write into the single-word vma_flags_t on 32-bit. Build the mask from config-gated per-mode masks so an unavailable bit is never materialised. This patch (of 6): make_uffd_wp_huge_pte() arms the UFFD_WP bit on a present HugeTLB PTE by calling huge_ptep_modify_prot_commit() with a ptent snapshot that was fetched without the corresponding huge_ptep_modify_prot_start(). The start helper is what atomically clears the entry so the kernel-owned snapshot stays consistent until the commit; without it, the hardware may set Dirty or Accessed in the live PTE between the original read and the commit, and huge_ptep_modify_prot_commit() (whose generic implementation just calls set_huge_pte_at()) then writes the stale snapshot back over the live hardware bits, losing the update. The non-hugetlb sibling make_uffd_wp_pte() does this correctly via ptep_modify_prot_start() / ptep_modify_prot_commit(). Mirror that pattern for the present-PTE branch. The migration case stays as-is -- migration entries are non-present, so there's no hardware update to race against.
Характеристики атаки
Последствия
Строка CVSS v3.1