[REGRESSION]: [PATCH mm-hotfixes v5 3/5] x86/mm/pat: acquire init_mm read lock on attribute change to avoid UAF
Borah, Chaitanya Kumar
chaitanya.kumar.borah at intel.com
Wed Jul 22 23:30:42 PDT 2026
Hello Lorenzo,
On 7/17/2026 11:00 PM, Lorenzo Stoakes (ARM) wrote:
> A previous commit protected us against races between ptdump and CPA
> collapse, however one still exists between attribute changes and collapse
> as reported by Denis V. Lunev (linked).
>
> When an attribute change arises, a lockless page table walker obtains a PTE
> entry, which is later written to via set_pte_atomic():
>
> ...
> -> change_page_attr_set_clr()
> -> __change_page_attr_set_clr()
> -> __change_page_attr()
> -> _lookup_address_cpa()
> -> lookup_address_in_pgd_attr()
> -> [ lockless page table walker ]
> -> set_pte_atomic()
>
> There is nothing preventing a concurrent CPA collapse which can free the
> PTE that was retrieved here, resulting in a use-after-free.
>
> With the mmap write lock taken on init_mm over CPA collapse, we can now
> resolve this race by acquiring an mmap read lock on init_mm over
> __change_page_attr_set_clr().
>
> This locks across the whole operation over which the walk and the PTE entry
> write occurs, solving the race.
>
> It is safe to do this here, as no spinlocks are held upon entry to
> __change_page_attr_set_clr().
>
> The CPA_COLLAPSE flag is only set by set_memory_rox(), which exclusively
> operates upon vmalloc ranges, and on x86 only within the module mapping
> space.
>
> This is important, because some callers directly invoke
> __change_page_attr_set_clr(), bypassing this lock. However, none of these
> operate within the module mapping space.
>
> * cpa_process_alias() - a recursive helper called by
> __change_page_attr_set_clr().
> * __set_memory_enc_pgtable() - operates on the direct mapping and (via
> __vmbus_establish_gpadl()) the vmalloc mapping space.
> * __set_pages_[n]p() - called by set_direct_map_[invalid, default,
> valid]_noflush(), __kernel_map_pages() - operates on the direct map.
> * kernel_[un]map_pages_in_pgd() - operates on EFI ranges.
>
> This work is based upon Denis V. Lunev's excellent analysis of the bug with
> gratitude.
>
This seems to be causing regression in our linux-next CI [1] on some of
the older machines (fi-elk-e7500, fi-ilk-650, fi-pnv-d510)
<4> [196.236867] ======================================================
<4> [196.236878] WARNING: possible circular locking dependency detected
<4> [196.236890] 7.2.0-rc4-next-20260720-next-20260720-g3fe08b9796f3+ #1
Tainted: G S U L
<4> [196.236906] ------------------------------------------------------
<4> [196.236916] core_hotunplug/5687 is trying to acquire lock:
<4> [196.236927] ffffffff839048b8 ((init_mm).mmap_lock){++++}-{4:4}, at:
change_page_attr_set_clr+0x10a/0x220
<4> [196.236958]
but task is already holding lock:
<4> [196.236969] ffff88810c852238 (&vm->mutex){+.+.}-{4:4}, at:
i915_ggtt_driver_release+0xab/0x260 [i915]
<4> [196.237572]
which lock already depends on the new lock.
<4> [196.237585]
the existing dependency chain (in reverse order) is:
<4> [196.237597]
-> #2 (&vm->mutex){+.+.}-{4:4}:
<4> [196.237617] i915_gem_shrinker_taints_mutex+0x35/0x70 [i915]
<4> [196.238267] i915_address_space_init+0x226/0x2a0 [i915]
<4> [196.238961] i915_ggtt_init_hw+0x2c/0x140 [i915]
<4> [196.239638] i915_driver_hw_probe+0x208/0x380 [i915]
<4> [196.240260] i915_driver_probe+0x113/0x5b0 [i915]
<4> [196.240883] i915_pci_probe+0xe0/0x1d0 [i915]
Detailed log can be seen found in [2]
We confirmed that reverting the patch solves the issue.
Could you please check why the patch causes this regression and provide
a fix if necessary?
Regards
Chaitanya
[1] https://intel-gfx-ci.01.org/tree/linux-next/combined-alt.html?
[2]
https://intel-gfx-ci.01.org/tree/linux-next/next-20260720/fi-ilk-650/igt@core_hotunplug@unbind-rebind.html
-- Bisect Logs --
git bisect start
# status: waiting for both good and bad commits
# good: [2b74f1f2024486c7a81915528b6aa7f8f5daa021] Merge patch series
"software node: provide support for fw_devlink"
git bisect good 2b74f1f2024486c7a81915528b6aa7f8f5daa021
# status: waiting for bad commit, 1 good commit known
# bad: [3fe08b9796f36ef437ab9328e7dd1e5ff2d66603] Add linux-next
specific files for 20260720
git bisect bad 3fe08b9796f36ef437ab9328e7dd1e5ff2d66603
# bad: [19137e3cffc35f327bd14d7b8b02f739f1e5c7bc] Merge branch 'main' of
ssh://git@gitolite.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git
git bisect bad 19137e3cffc35f327bd14d7b8b02f739f1e5c7bc
# skip: [4f9e9b2e992ca79e090771e244bc2096709e13c6] Merge branch
'mm-unstable' of
ssh://git@gitolite.kernel.org/pub/scm/linux/kernel/git/akpm/mm
git bisect skip 4f9e9b2e992ca79e090771e244bc2096709e13c6
# good: [1aa4e2ed7caafbbbedff89fb226a982413469baf] dt-bindings: clock:
Replace bouncing emails
git bisect good 1aa4e2ed7caafbbbedff89fb226a982413469baf
# good: [daec24a5ed5da77a108e246ad77aa8b889911f93] wifi: iwlwifi:
validate payload length in iwl_pnvm_complete_fn
git bisect good daec24a5ed5da77a108e246ad77aa8b889911f93
# bad: [247e42b76590a27408e5eea7009067cac5ad9feb] Merge branch
'for-next' of
ssh://git@gitolite.kernel.org/pub/scm/linux/kernel/git/peter.chen/cix.git
git bisect bad 247e42b76590a27408e5eea7009067cac5ad9feb
# bad: [d623282ba80e07d3bd7608d905b143041f865f3b] Merge branch
'tty-linus' of
ssh://git@gitolite.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git
git bisect bad d623282ba80e07d3bd7608d905b143041f865f3b
# good: [6f5156d7a31a8c3b0f34af4675c9299c8f877cbe] Merge tag
'pm-7.2-rc4' of
git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
git bisect good 6f5156d7a31a8c3b0f34af4675c9299c8f877cbe
# good: [7d6ca51a444234ca436d7c19282825797507fe82] Merge tag
'drm-fixes-2026-07-18-1' of https://gitlab.freedesktop.org/drm/kernel
git bisect good 7d6ca51a444234ca436d7c19282825797507fe82
# bad: [499079fbac564b04cce6a750111bf1c36aaeb4d5] Merge branch
'mm-hotfixes-unstable' of
ssh://git@gitolite.kernel.org/pub/scm/linux/kernel/git/akpm/mm
git bisect bad 499079fbac564b04cce6a750111bf1c36aaeb4d5
# good: [a2b81de43ca64832fe09844bbf97d1251115d80f] Merge tag
'io_uring-7.2-20260717' of
git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux
git bisect good a2b81de43ca64832fe09844bbf97d1251115d80f
# bad: [b55b09b68a9cd81d2c1f4004e4c258cbfa61b16f] x86/mm/pat: acquire
init_mm read lock on attribute change to avoid UAF
git bisect bad b55b09b68a9cd81d2c1f4004e4c258cbfa61b16f
# good: [841587a3eaad22b288d9701f783e20a5046e76b4] mm/hugetlb: fix null
nodemask in alloc_fresh_hugetlb_folio
git bisect good 841587a3eaad22b288d9701f783e20a5046e76b4
# good: [2272f397e66bd9f78c2e1f524f8e7b1e01e15005] ocfs2: fix boundary
check in ocfs2_check_dir_entry() to use buffer offset
git bisect good 2272f397e66bd9f78c2e1f524f8e7b1e01e15005
# good: [a5bba3c7f83071427f5f770b53ce5c59f8ed0af0] fs/proc/task_mmu: fix
PAGEMAP_SCAN written state for PMD holes
git bisect good a5bba3c7f83071427f5f770b53ce5c59f8ed0af0
# good: [f539349310317df97b5f1b501c4c6dc2a73c3c37] mm/vmalloc: acquire
init_mm lock on huge vmap to avoid ptdump UAF
git bisect good f539349310317df97b5f1b501c4c6dc2a73c3c37
# good: [c6d14c413d47a772a54f6aa7e545a15abc06b1d0] x86/mm/pat: acquire
init_mm write lock on collapse to avoid UAF
git bisect good c6d14c413d47a772a54f6aa7e545a15abc06b1d0
# first bad commit: [b55b09b68a9cd81d2c1f4004e4c258cbfa61b16f]
x86/mm/pat: acquire init_mm read lock on attribute change to avoid UAF
> Link: https://lore.kernel.org/all/20260626163213.2284080-1-den@openvz.org/
> Fixes: 41d88484c71c ("x86/mm/pat: restore large ROX pages after fragmentation")
> Cc: stable at vger.kernel.org
> Signed-off-by: Lorenzo Stoakes (ARM) <ljs at kernel.org>
> ---
> arch/x86/mm/pat/set_memory.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/arch/x86/mm/pat/set_memory.c b/arch/x86/mm/pat/set_memory.c
> index d1e63f7d267f..301fb9e77d91 100644
> --- a/arch/x86/mm/pat/set_memory.c
> +++ b/arch/x86/mm/pat/set_memory.c
> @@ -2122,7 +2122,9 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages,
> cpa.curpage = 0;
> cpa.force_split = force_split;
>
> - ret = __change_page_attr_set_clr(&cpa, 1);
> + /* Avoid race with concurrent CPA collapse. */
> + scoped_guard(mmap_read_lock, &init_mm)
> + ret = __change_page_attr_set_clr(&cpa, 1);
>
> /*
> * Check whether we really changed something:
>
More information about the linux-arm-kernel
mailing list