[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <13c5fe73-9e11-4465-b401-fc96a22dc5d1@redhat.com>
Date: Thu, 22 May 2025 17:14:45 +0200
From: David Hildenbrand <david@...hat.com>
To: Pu Lehui <pulehui@...weicloud.com>, mhiramat@...nel.org, oleg@...hat.com,
peterz@...radead.org, akpm@...ux-foundation.org, Liam.Howlett@...cle.com,
lorenzo.stoakes@...cle.com, vbabka@...e.cz, jannh@...gle.com,
pfalcato@...e.de
Cc: linux-mm@...ck.org, linux-kernel@...r.kernel.org, pulehui@...wei.com
Subject: Re: [RFC PATCH] mm/mmap: Fix uprobe anon page be overwritten when
expanding vma during mremap
On 22.05.25 16:37, Pu Lehui wrote:
>
>
> On 2025/5/21 18:25, David Hildenbrand wrote:
>> On 21.05.25 11:25, Pu Lehui wrote:
>>> From: Pu Lehui <pulehui@...wei.com>
>>>
>>> We encountered a BUG alert triggered by Syzkaller as follows:
>>> BUG: Bad rss-counter state mm:00000000b4a60fca type:MM_ANONPAGES
>>> val:1
>>>
>>> And we can reproduce it with the following steps:
>>> 1. register uprobe on file at zero offset
>>> 2. mmap the file at zero offset:
>>> addr1 = mmap(NULL, 2 * 4096, PROT_NONE, MAP_PRIVATE, fd, 0);
>>
>> So, here we will install a uprobe.
>>
>>> 3. mremap part of vma1 to new vma2:
>>> addr2 = mremap(addr1, 4096, 2 * 4096, MREMAP_MAYMOVE);
>>
>> Okay, so we'll essentially move the uprobe as we mremap.
>>
>>
>>> 4. mremap back to orig addr1:
>>> mremap(addr2, 4096, 4096, MREMAP_MAYMOVE | MREMAP_FIXED, addr1);
>>
>> And here, we would expect to move the uprobe again.
>>
>>>
>>> In the step 3, the vma1 range [addr1, addr1 + 4096] will be remap to new
>>> vma2 with range [addr2, addr2 + 8192], and remap uprobe anon page from
>>> the vma1 to vma2, then unmap the vma1 range [addr1, addr1 + 4096].
>>> In tht step 4, the vma2 range [addr2, addr2 + 4096] will be remap back
>>> to the addr range [addr1, addr1 + 4096]. Since the addr range [addr1 +
>>> 4096, addr1 + 8192] still maps the file, it will take
>>> vma_merge_new_range to merge these two addr ranges, and then do
>>> uprobe_mmap in vma_complete. Since the merged vma pgoff is also zero
>>> offset, it will install uprobe anon page to the merged vma.
>>
>> Oh, so we're installing the uprobe into the extended VMA before moving
>> the page tables.
> Yep!
>>
>> Gah.
>>
>>> However, the
>>> upcomming move_page_tables step, which use set_pte_at to remap the vma2
>>> uprobe anon page to the merged vma, will over map the old uprobe anon
>>> page in the merged vma, and lead the old uprobe anon page to be orphan.
>>
>> Right, when moving page tables we don't expect there to already be
>> something from the uprobe code.
>>
>>>
>>> Since the uprobe anon page will be remapped to the merged vma, we can
>>> remove the unnecessary uprobe_mmap at merged vma, that is, do not
>>> perform uprobe_mmap when there is no vma in the addr range to be
>>> expaned.
>>
>> Hmmm, I'll have to think about other corner cases ....
>>
> looking forward to it
I think, the rule is that we must not install a uprobe for the range
that we will be actually moving the page tables for.
So, for the range we're effectively moving (not the one we're extending).
Because logically, the uprobe will be already handled by the existing
page tables that we're moving.
For the range we're extending, we must call uprobe handling code ...
Alternatively, maybe we could call uprobe handling code after moving the
page tables. We'd probably find that the uprobe is already installed and
do nothing (so the theory :) ). ... if that would simplify anything.
--
Cheers,
David / dhildenb
Powered by blists - more mailing lists