From: sashiko-bot@kernel.org
To: tao <tao.wangtao@honor.com>
Cc: damon@lists.linux.dev
Subject: Re: [PATCH 13/15] mm: support setup and upgrade of ANON_VMA_LAZY folios
Date: Wed, 27 May 2026 13:02:31 +0000 [thread overview]
Message-ID: <20260527130231.B48871F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260527110147.17815-14-tao.wangtao@honor.com>
Thank you for your contribution! Sashiko AI review found 6 potential issue(s) to consider:
- [Critical] Dereferencing `vma->vm_mm` before taking the VMA reference causes a Use-After-Free on the `mm_struct`.
- [Critical] Upgrading a VMA leaves dangling pointers in `folio->mapping`, leading to Use-After-Free.
- [High] rmap_walk_anon() silently aborts instead of retrying when a lazy mapping is concurrently upgraded.
- [High] Toggling the `anon_vma_lazy` sysctl at runtime causes `fork()` to crash with `VM_BUG_ON_VMA`.
- [High] Large anonymous folios spanning split VMAs break rmap traversal because only one VMA updates the folio mapping.
- [High] TOCTOU race in `__folio_rmap_sanity_checks()` causes a kernel panic when a folio mapping is concurrently upgraded.
--
commit a797e29fa9a2081d4af94616e5d30308d998bb4d
Author: tao <tao.wangtao@honor.com>
Subject: mm: support setup and upgrade of ANON_VMA_LAZY folios
This commit introduces ANON_VMA_LAZY folios setup and upgrade mechanisms
across mapping, duplicating, and rmap walk paths.
> rmap_walk_anon() detects ANON_VMA_LAZY upgrades and retries
> the walk to ensure the mapping is handled correctly.
[Severity: High]
The commit message mentions that rmap_walk_anon() retries the walk if it
detects an ANON_VMA_LAZY upgrade. Is this accurate?
It appears there is no retry loop. If folio_lock_anon_vma_lazy_read()
returns NULL because the mapping was upgraded concurrently,
rmap_walk_anon_lock() returns ANON_RMAP_NULL and rmap_walk_anon()
immediately aborts.
Could this cause reverse mapping operations like try_to_unmap() to silently
skip the folio, leading to memory leaks and failed migrations?
> diff --git a/include/linux/rmap.h b/include/linux/rmap.h
> --- a/include/linux/rmap.h
> +++ b/include/linux/rmap.h
> @@ -392,6 +392,14 @@ static __always_inline void __folio_rmap_sanity_checks(const struct folio *folio
> unsigned long mapping = (unsigned long)folio->mapping;
> struct anon_vma *anon_vma;
>
> + if (folio_test_anon_vma_lazy(folio)) {
> + struct vm_area_struct *root_vma =
> + (void *)(mapping - FOLIO_MAPPING_ANON_VMA_LAZY);
> +
> + VM_WARN_ON_FOLIO(!rcuref_read(&root_vma->vm_rcuref), folio);
> + return;
> + }
> +
> anon_vma = (void *)(mapping - FOLIO_MAPPING_ANON);
> VM_WARN_ON_FOLIO(atomic_read(&anon_vma->refcount) == 0, folio);
[Severity: High]
Is there a TOCTOU race here when a folio mapping is concurrently upgraded?
The code reads folio->mapping into the local mapping variable, then
folio_test_anon_vma_lazy() re-reads folio->mapping. If the mapping is
upgraded to a regular anon_vma between these reads, the test returns false,
falling through to evaluate anon_vma using the first read which still has
the lazy tag.
This would yield an unaligned pointer (root_vma + 2), and dereferencing it
in atomic_read() would panic the kernel.
[ ... ]
> @@ -431,6 +439,31 @@ void hugetlb_add_anon_rmap(struct folio *, struct vm_area_struct *,
> +static inline void folio_upgrade_anon_vma_lazy(struct folio *folio,
> + struct vm_area_struct *vma)
> +{
> + unsigned long anon_tree = (unsigned long)vma->anon_vma;
> +
> + VM_BUG_ON_VMA(!anon_tree || !IS_ALIGNED(anon_tree, sizeof(long)), vma);
[Severity: High]
What happens if the anon_vma_lazy_enabled() sysctl is toggled to false at
runtime?
If anon_vma_fork() skips upgrading the parent VMA's lazy mapping, later in
fork(), copy_page_range() calls folio_try_dup_anon_rmap() which then
invokes folio_upgrade_anon_vma_lazy() here.
Since src_vma->anon_vma was never upgraded and holds a tagged
ANON_VMA_TREE_VMA pointer, wouldn't this IS_ALIGNED assertion fail and
panic the kernel?
> + anon_tree = anon_tree + FOLIO_MAPPING_ANON;
> + WRITE_ONCE(folio->mapping, (struct address_space *)anon_tree);
> +}
[Severity: High]
Can large anonymous folios spanning split VMAs break rmap traversal here?
When an ANON_VMA_LAZY VMA is split, a large folio can span both resulting
VMAs. During fork(), the first VMA is upgraded to a regular anon_vma and
updates folio->mapping. When the second VMA is processed,
folio_test_anon_vma_lazy() is already false, so the folio's mapping isn't
updated to reflect the second VMA.
Will future rmap walks traverse the first VMA but miss the second,
stranding PTEs and leaking memory?
[Severity: Critical]
Does upgrading a VMA leave dangling pointers in folio->mapping?
When a lazy VMA is upgraded to a regular anon_vma (for example, via
vma_upgrade_anon_vma_lazy() during khugepaged operations or mprotect), it
seems the VMA drops its reference to root_vma, but the page tables aren't
walked to update folio->mapping for existing folios.
These folios would retain the old root_vma + FOLIO_MAPPING_ANON_VMA_LAZY
pointer. When the root_vma is eventually freed, could any rmap walk on
these folios dereference the dangling pointer, causing a use-after-free on
the freed VMA slab object?
[Severity: Critical]
While not explicitly in the provided diff context, can dereferencing
vma->vm_mm before taking the VMA reference cause a use-after-free on the
mm_struct?
In folio_resolve_anon_vma_lazy(), the code reads mm = vma->vm_mm before
calling vma_get(anon_lazy_root). Because the VMA is allocated from a
SLAB_TYPESAFE_BY_RCU cache, it can be freed and recycled to a completely
different process concurrently.
The read mm pointer may point to a freed mm_struct. Calling
vma_lookup(mm, addr) subsequently dereferences this stale mm pointer,
leading to a use-after-free.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260527110147.17815-1-tao.wangtao@honor.com?part=13
next prev parent reply other threads:[~2026-05-27 13:02 UTC|newest]
Thread overview: 82+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-27 11:01 [PATCH 0/15] mm: introduce ANON_VMA_LAZY for deferred anon_vma creation tao
2026-05-27 11:01 ` [PATCH 01/15] mm/rmap: introduce anon_rmap APIs for anonymous folios tao
2026-05-27 11:32 ` sashiko-bot
2026-05-27 11:44 ` Lorenzo Stoakes
2026-05-28 7:47 ` wangtao
2026-05-27 11:01 ` [PATCH 02/15] mm: convert anon_vma rmap APIs to anon_rmap tao
2026-05-27 11:49 ` Lorenzo Stoakes
2026-05-28 8:55 ` wangtao
2026-05-27 11:01 ` [PATCH 03/15] mm: introduce anon_vma_tree_t for multiple anon_vma topologies tao
2026-05-27 11:56 ` Lorenzo Stoakes
2026-05-28 9:00 ` wangtao
2026-05-27 11:01 ` [PATCH 04/15] mm: switch to anon_vma_tree_t APIs in preparation for ANON_VMA_LAZY tao
2026-05-27 11:53 ` sashiko-bot
2026-05-27 11:01 ` [PATCH 05/15] mm: add CONFIG_ANON_VMA_LAZY and folio helpers tao
2026-05-27 11:01 ` [PATCH 06/15] mm: add CONFIG_VMA_REF and VMA helpers tao
2026-05-27 11:42 ` sashiko-bot
2026-05-27 11:01 ` [PATCH 07/15] mm: replace direct FOLIO_MAPPING_ANON usage with helpers tao
2026-05-27 11:43 ` sashiko-bot
2026-05-27 11:01 ` [PATCH 08/15] mm: prepare rmap infrastructure for ANON_VMA_LAZY tao
2026-05-27 14:01 ` sashiko-bot
2026-05-27 11:01 ` [PATCH 09/15] mm: implement ANON_VMA_LAZY rmap semantics tao
2026-05-27 12:15 ` sashiko-bot
2026-05-27 11:01 ` [PATCH 10/15] mm: defer anon_vma creation with ANON_VMA_LAZY tao
2026-05-27 12:29 ` sashiko-bot
2026-05-27 11:01 ` [PATCH 11/15] mm: handle ANON_VMA_LAZY in huge page operations tao
2026-05-27 12:21 ` sashiko-bot
2026-05-27 11:01 ` [PATCH 12/15] mm: handle ANON_VMA_LAZY during migration tao
2026-05-27 12:23 ` sashiko-bot
2026-05-27 11:01 ` [PATCH 13/15] mm: support setup and upgrade of ANON_VMA_LAZY folios tao
2026-05-27 13:02 ` sashiko-bot [this message]
2026-05-27 11:01 ` [PATCH 14/15] mm: support merging of ANON_VMA_LAZY VMAs tao
2026-05-27 12:49 ` sashiko-bot
2026-05-27 11:01 ` [PATCH 15/15] mm: enable CONFIG_ANON_VMA_LAZY on arm64 and x86_64 tao
2026-05-27 17:19 ` sashiko-bot
2026-05-27 11:23 ` [PATCH 0/15] mm: introduce ANON_VMA_LAZY for deferred anon_vma creation Pedro Falcato
2026-05-28 6:45 ` wangtao
2026-05-28 7:14 ` Lorenzo Stoakes
2026-05-27 11:30 ` Lorenzo Stoakes
2026-05-28 7:11 ` wangtao
2026-05-28 7:22 ` Lorenzo Stoakes
2026-05-27 14:33 ` Lorenzo Stoakes
2026-05-28 7:57 ` wangtao
2026-05-28 8:14 ` Lorenzo Stoakes
2026-05-28 23:31 ` Barry Song
2026-05-29 2:20 ` wangzicheng
2026-05-29 6:56 ` Lorenzo Stoakes
2026-05-29 6:45 ` Lorenzo Stoakes
2026-05-29 9:41 ` wangtao
2026-05-29 12:03 ` Lorenzo Stoakes
2026-06-01 1:46 ` wangtao
2026-06-02 2:15 ` Barry Song
2026-06-02 2:46 ` Lance Yang
2026-06-02 15:37 ` Lorenzo Stoakes
2026-06-02 19:44 ` Pedro Falcato
2026-06-02 23:03 ` Barry Song
2026-06-03 7:07 ` Lorenzo Stoakes
2026-06-02 19:56 ` Harry Yoo
2026-06-02 22:27 ` Barry Song
2026-06-02 20:47 ` Lorenzo Stoakes
2026-05-29 15:07 ` Jonathan Corbet
2026-05-29 15:40 ` Lorenzo Stoakes
2026-05-30 11:28 ` Barry Song
2026-06-02 16:07 ` Harry Yoo
2026-06-03 2:59 ` wangtao
2026-06-03 3:12 ` wangtao
2026-06-03 7:54 ` Lorenzo Stoakes
2026-06-03 11:05 ` wangtao
2026-06-03 11:53 ` Lorenzo Stoakes
2026-06-04 3:50 ` wangtao
2026-06-03 20:25 ` David Hildenbrand (Arm)
2026-06-03 22:14 ` Barry Song
2026-06-04 4:03 ` wangtao
2026-06-04 4:20 ` Barry Song
2026-06-04 7:35 ` wangtao
2026-06-09 15:26 ` Suren Baghdasaryan
2026-06-09 15:49 ` David Hildenbrand (Arm)
2026-06-04 3:10 ` xu.xin16
2026-06-04 4:10 ` wangtao
2026-06-05 9:38 ` David Hildenbrand (Arm)
2026-06-05 10:07 ` Lorenzo Stoakes
2026-06-05 10:56 ` David Hildenbrand (Arm)
2026-06-04 9:40 ` Lorenzo Stoakes
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260527130231.B48871F000E9@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=damon@lists.linux.dev \
--cc=sashiko-reviews@lists.linux.dev \
--cc=tao.wangtao@honor.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.