From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1794585665; b=11rXaEtwx6Tai9iSLsZSKDxpX80HF6GUUFIiSe7HEDu/sUSlN+vwBbHShO0TMPw0yJwA prGg/eTX+ngqniQmY9/4Uicg8H4goMwbsGRJ+bWZai6PS4aj0XMxA2s3hbO3T43tC3HtY jxQRESQULjbikVLRDAxzm4N0pCeU4FjMKq+HUdgYK3TVJkyplHgeddK36pBpNLSlV4uxu Q6MO7W2AZRtVDhGzBEcOsMwdAfI5ngR60G+6v43jCg46H33+l6Levd0b5TAjHRHuKEm9/ ENA7c5tVQptwB39/MLvtpsQUq8wEH9gTCx7x7JaHC1xcss3qD/43Kx7ph7Mo5SbMj5Q== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1794585665; h=Received:DKIM-Signature:From:To:Cc:Subject:Date:Message-ID:X-Mailer: In-Reply-To:References:User-Agent:X-stable:X-Patchwork-Hint: MIME-Version:Content-Type:Content-Transfer-Encoding; bh=9uirqWCCUacwBp0tOh1ZI1O07quVnKOx44N7pbiJlxg=; b=0q4w3CsDAtgTwBMGpeHlX4FHsWFTTP4gTOBnKUKlNA1xE2Bp4gI5RGG/rTQrmMrHTFzk zRxhOyjaU5tHty4FnqSNkvVzboScjuYwWFrdJfse27oKTYM2HzNzUEnxnXLyZ6MupCU3j aBzSD77OTfG/8eQx6nD/DbAZckbyETRhOtshWqUCzVzjviPKaP8wb8Ttxr9FYTR/G2LyT sFZrKAC6Hnd5NQbUduLGC2YbaiC4WDXN7iRDhN/hIi0ibe5ZJ5SxZYJLWKZ3lRnMbiAC1 7tDzQLsN3lnh7rksbbhuLq+QsMrW+lOhFP+EWXpjH0Z5QwqkKhjPr7CexiA3hzn/0yQ== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=McQMKuac; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D3FB6606B2E8; Fri, 13 Nov 2026 16:01:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=linuxfoundation.org header.i=@linuxfoundation.org header.a=rsa-sha256 header.s=korg header.b=McQMKuac Received: by smtp.kernel.org (Postfix) with ESMTPSA id 6FA991F000C4; Fri, 13 Nov 2026 16:01:05 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linuxfoundation.org; s=korg; t=1794585665; bh=9uirqWCCUacwBp0tOh1ZI1O07quVnKOx44N7pbiJlxg=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=McQMKuac1qNZPQFUvmjs1GE+ieJOXpZmYYXrloI7pgTIaPmvu7FfFtr6JkCSz2lxP s1yu9d+hED4UCeKRVIObMWhcB3viYsefX7/hRRRIoL/Ud6sfknZ64d8gziunNWSIao bTIdDBDhwsnvWYZ9HbfvkAyhxBU3WUuCES+9SYLY= From: Greg Kroah-Hartman To: stable@vger.kernel.org Cc: Greg Kroah-Hartman , patches@lists.linux.dev, Samarth Narang , Lance Yang , Andrew Morton , "Lorenzo Stoakes (ARM)" , "Kiryl Shutsemau (Meta)" , "David Hildenbrand (Arm)" , Mel Gorman , Chengming Zhou , "Liam R. Howlett" , Vlastimil Babka , Mike Rapoport , Suren Baghdasaryan , Michal Hocko , =?UTF-8?q?J=C3=A9r=C3=B4me=20Glisse?= , Andrea Arcangeli , Peter Xu , Bobby Powers , Brian Geffon , Denis Plotnikov , Doug Gilbert , Hugh Dickins , Johannes Weiner , Martin Cracauer , Marty McFadden , Maya Gokhale , Pavel Emelyanov , Rik van Riel , Shaohua Li , James Houghton , Jonathan Corbet , Paolo Bonzini , Sean Christopherson , SJ Park , Zi Yan , Mohammed EL Kadiri , Sasha Levin , Xu Xin Subject: [PATCH 7.3 237/507] mm/ksm: fix userfaultfd protection during merge and unmerge Date: Fri, 13 Nov 2026 10:49:01 -0500 Message-ID: <20261113153802.542794380@linuxfoundation.org> X-Mailer: git-send-email 2.56.0 In-Reply-To: <20261113153753.358973689@linuxfoundation.org> References: <20261113153753.358973689@linuxfoundation.org> User-Agent: quilt/0.69 X-stable: review X-Patchwork-Hint: ignore X-Mailing-List: stable@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 7.3-stable review patch. If anyone has any objections, please let me know. ------------------ From: Lance Yang [ Upstream commit 990d6c2194a938a19a8cf94c6cfd75171345089b ] KSM loses userfaultfd protection when replace_page() builds a new PTE from vma->vm_page_prot. Dropping its uffd bit lets a subsequent write go through ordinary COW instead of userfaultfd write protection handling. For RWP, a merged page also becomes readable without faulting. Keeping the uffd bit and restoring PAGE_NONE fixes merging, but we also have to handle unmerging. An existing KSM page can be protected with RWP before MADV_UNMERGEABLE, so unmerging already needs fixing independently of preserving RWP during merging. Unsharing replaces a shared page with a private one and should leave userfaultfd protection in place, as do_wp_page() already does for write protection. Currently, an unshare fault reaches do_uffd_rwp() before it can proceed to do_wp_page(). - With synchronous RWP, handle_userfault() returns VM_FAULT_SIGBUS. break_ksm() then reports success with a KSM page still merged. - With asynchronous RWP, protection is cleared before unsharing. Preserve the uffd bit when merging, and restore PAGE_NONE for RWP. Let FAULT_FLAG_UNSHARE skip RWP fault handling and keep PAGE_NONE on each private copy as well. Unsharing can then complete with RWP still armed for a subsequent access. Link: https://lore.kernel.org/20261026130054.91461-1-lance.yang@linux.dev Link: https://lore.kernel.org/all/20261019010934.697895-1-samarth.colleges@gmail.com/ Link: https://lore.kernel.org/all/20261020055518.36087-1-lance.yang@linux.dev/ Fixes: 63b2d4174c4a ("userfaultfd: wp: add the writeprotect API to userfaultfd ioctl") Fixes: 2d427bb01639 ("mm/userfaultfd: add RWP fault delivery and expose UFFDIO_REGISTER_MODE_RWP") Signed-off-by: Samarth Narang Signed-off-by: Lance Yang Signed-off-by: Andrew Morton Co-developed-by: Samarth Narang Acked-by: Lorenzo Stoakes (ARM) Reviewed-by: Kiryl Shutsemau (Meta) Acked-by: David Hildenbrand (Arm) Cc: Mel Gorman Cc: Xu Xin " Cc: Chengming Zhou Cc: Liam R. Howlett Cc: Vlastimil Babka Cc: Mike Rapoport Cc: Suren Baghdasaryan Cc: Michal Hocko Cc: Jérôme Glisse Cc: Andrea Arcangeli Cc: Peter Xu Cc: Bobby Powers Cc: Brian Geffon Cc: Denis Plotnikov Cc: Doug Gilbert Cc: Hugh Dickins Cc: Johannes Weiner Cc: Martin Cracauer Cc: Marty McFadden Cc: Maya Gokhale Cc: Pavel Emelyanov Cc: Rik van Riel Cc: Shaohua Li Cc: James Houghton Cc: Jonathan Corbet Cc: Paolo Bonzini Cc: Sean Christopherson Cc: SJ Park Cc: Zi Yan Cc: Mohammed EL Kadiri Cc: Signed-off-by: Sasha Levin --- mm/ksm.c | 8 +++++++- mm/memory.c | 14 ++++++++++---- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/mm/ksm.c b/mm/ksm.c index b1f361983e553..5b3559bf4c8f8 100644 --- a/mm/ksm.c +++ b/mm/ksm.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -1462,9 +1463,14 @@ static int replace_page(struct vm_area_struct *vma, struct page *page, dec_mm_counter(mm, MM_ANONPAGES); } - /* Preserve soft-dirty when replacing the page. */ + /* Preserve soft-dirty and uffd protection when replacing the page. */ if (pte_soft_dirty(orig_pte)) newpte = pte_mksoft_dirty(newpte); + if (pte_uffd(orig_pte)) { + newpte = pte_mkuffd(newpte); + if (userfaultfd_rwp(vma)) + newpte = pte_modify(newpte, PAGE_NONE); + } flush_cache_page(vma, addr, pte_pfn(ptep_get(ptep))); /* diff --git a/mm/memory.c b/mm/memory.c index 243b34f2e54fa..88f7953afbabc 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -4060,8 +4060,11 @@ static vm_fault_t wp_page_copy(struct vm_fault *vmf) if (unlikely(unshare)) { if (pte_soft_dirty(vmf->orig_pte)) entry = pte_mksoft_dirty(entry); - if (pte_uffd(vmf->orig_pte)) + if (pte_uffd(vmf->orig_pte)) { entry = pte_mkuffd(entry); + if (userfaultfd_rwp(vma)) + entry = pte_modify(entry, PAGE_NONE); + } } else { entry = maybe_mkwrite(pte_mkdirty(entry), vma); } @@ -6591,9 +6594,12 @@ static vm_fault_t handle_pte_fault(struct vm_fault *vmf) * VM_UFFD_RWP VMA, a protnone PTE without the uffd bit is * NUMA hinting and must still fall through to do_numa_page(). */ - if (userfaultfd_pte_rwp(vmf->vma, vmf->orig_pte)) - return do_uffd_rwp(vmf); - return do_numa_page(vmf); + if (userfaultfd_pte_rwp(vmf->vma, vmf->orig_pte)) { + if (!(vmf->flags & FAULT_FLAG_UNSHARE)) + return do_uffd_rwp(vmf); + } else { + return do_numa_page(vmf); + } } spin_lock(vmf->ptl); -- 2.53.0