All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: tao <tao.wangtao@honor.com>
Cc: damon@lists.linux.dev
Subject: Re: [PATCH 08/15] mm: prepare rmap infrastructure for ANON_VMA_LAZY
Date: Wed, 27 May 2026 14:01:58 +0000	[thread overview]
Message-ID: <20260527140159.53AAA1F00A3D@smtp.kernel.org> (raw)
In-Reply-To: <20260527110147.17815-9-tao.wangtao@honor.com>

Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
- [Critical] Race condition and missing synchronization in `anon_vma_lazy_lock_read()` and `anon_vma_tree_lock_write()` for lazy VMAs.
- [Critical] Ignored return value of `vma_get()` in `anon_vma_lazy_lock_read()` leads to Use-After-Free and refcount underflow.
- [High] Off-by-one boundary check in `anon_rmap_iter_first_vma()` causes false positive VMA overlap detection and out-of-bounds page table accesses.
--

commit 411934596db1ffd0b45c2469ce0c285daaf6e6e1
Author: tao <tao.wangtao@honor.com>

mm: prepare rmap infrastructure for ANON_VMA_LAZY

Introduce ANON_VMA_LAZY helpers and prepare the anon_rmap and anon_vma_tree
infrastructure for the upcoming ANON_VMA_LAZY feature.

> diff --git a/include/linux/rmap.h b/include/linux/rmap.h
> index 9802bce926959..ebe9f3f61170d 100644
> --- a/include/linux/rmap.h
> +++ b/include/linux/rmap.h

[ ... ]

> @@ -1015,8 +1047,17 @@ static inline struct vm_area_struct *anon_rmap_iter_first_vma(
>  	anon_rmap_t anon_rmap, unsigned long start, unsigned long last,
>  	struct anon_vma_chain **avc)
>  {
> -	struct anon_vma *anon_vma = anon_rmap_to_anon_vma(anon_rmap);
> +	struct anon_vma *anon_vma;
> +
> +	*avc = NULL;
> +	if (!anon_rmap_is_anon_vma(anon_rmap)) {
> +		struct vm_area_struct *vma = anon_rmap_to_vma(anon_rmap);
>  
> +		if (vma->vm_pgoff + vma_pages(vma) < start || vma->vm_pgoff > last)
                                                    ^^^^^^

[Severity: High]
Does this off-by-one boundary check cause false positive VMA overlap detection?

It looks like the exclusive end check uses < start instead of <= start.
If a folio's start offset is exactly at the VMA's exclusive end, this check
evaluates to false, incorrectly implying the folio overlaps with the VMA.

The iteration would then yield the non-overlapping VMA to rmap_walk_anon(),
which passes the offset to vma_address().

Because the offset is outside the VMA bounds, vma_address() calculates an
address >= vma->vm_end and returns -EFAULT. This triggers
VM_BUG_ON_VMA(address == -EFAULT, vma) in rmap_walk_anon().

> +			return NULL; /* No overlap in the VMA range. */
> +		return vma;
> +	} else
> +		anon_vma = anon_rmap_to_anon_vma(anon_rmap);
>  	*avc = anon_vma_interval_tree_iter_first(&anon_vma->rb_root, start, last);
>  	return *avc ? (*avc)->vma : NULL;
>  }

[ ... ]

> diff --git a/mm/internal.h b/mm/internal.h
> index 639f9c287f4c2..6b703646f66db 100644
> --- a/mm/internal.h
> +++ b/mm/internal.h

[ ... ]

> +/*
> + * ANON_VMA_TREE_VMA is just a VMA, without anon_vma or anon_vma_chain,
> + * so no protection is needed.
> + */
>  static inline void anon_vma_tree_lock_write(anon_vma_tree_t anon_tree)
>  {
>  	struct anon_vma *anon_vma = anon_vma_tree_anon_vma(anon_tree);
>  
> -	anon_vma_lock_write(anon_vma);
> +	if (anon_vma)
> +		anon_vma_lock_write(anon_vma);

[Severity: Critical]
Can this missing synchronization lead to a use-after-free of page table pages?

Here, anon_vma_tree_lock_write() acts as a no-op for lazy VMAs.
In mm/rmap.c, anon_vma_lazy_lock_read() only increments vm_rcuref via vma_get()
without acquiring any synchronization locks.

Consequently, operations that traverse page tables (like rmap_walk_anon()) run
completely lockless and concurrently with page table structural changes like
vma_adjust_trans_huge() in __split_vma() or VMA teardowns in free_pgtables().

vma_get() doesn't prevent free_pgd_range() from unmapping and freeing the page
tables. This allows page tables to be freed while page_vma_mapped_walk() is
traversing them, which can lead to a use-after-free of page table pages.

>  }
>  
>  static inline int anon_vma_tree_trylock_write(anon_vma_tree_t anon_tree)

[ ... ]

> diff --git a/mm/rmap.c b/mm/rmap.c
> index 58f470e0c3ffd..d13395a082c60 100644
> --- a/mm/rmap.c
> +++ b/mm/rmap.c

[ ... ]

> +static void anon_vma_lazy_lock_read(struct vm_area_struct *vma)
> +{
> +	vma_get(vma);

[Severity: Critical]
Is it safe to ignore the return value of vma_get() here?

vma_get() returns NULL if the VMA's reference count is already zero, indicating
it is scheduled for freeing.

Because this failure is ignored and the function returns void, callers like
anon_rmap_lock_read() might proceed to traverse a dying or freed VMA, assuming
the lock and reference were successfully acquired.

This can lead to a use-after-free when accessing VMA fields.

Additionally, anon_vma_lazy_unlock_read() will later call vma_put(), which
invokes rcuref_put() on an already-zero refcount, causing a refcount underflow
and potential double-free of the VMA memory.

> +}
> +
> +static bool anon_vma_lazy_trylock_read(struct vm_area_struct *vma)
> +{
> +	return (bool)vma_get(vma);
> +}
> +
> +static void anon_vma_lazy_unlock_read(struct vm_area_struct *vma)
> +{
> +	vma_put(vma);
> +}

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260527110147.17815-1-tao.wangtao@honor.com?part=8

  reply	other threads:[~2026-05-27 14: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 [this message]
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
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=20260527140159.53AAA1F00A3D@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.