Commit c38a55c9 authored by Jann Horn's avatar Jann Horn Committed by Liu Shixin
Browse files

userfaultfd: don't BUG_ON() if khugepaged yanks our page table

stable inclusion
from stable-v6.6.51
commit 4a594acc12d5954cdc71d4450a386748bf3d136a
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/IAU9P2
CVE: CVE-2024-46838

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=4a594acc12d5954cdc71d4450a386748bf3d136a

--------------------------------

commit 4828d207dc5161dc7ddf9a4f6dcfd80c7dd7d20a upstream.

Since khugepaged was changed to allow retracting page tables in file
mappings without holding the mmap lock, these BUG_ON()s are wrong - get
rid of them.

We could also remove the preceding "if (unlikely(...))" block, but then we
could reach pte_offset_map_lock() with transhuge pages not just for file
mappings but also for anonymous mappings - which would probably be fine
but I think is not necessarily expected.

Link: https://lkml.kernel.org/r/20240813-uffd-thp-flip-fix-v2-2-5efa61078a41@google.com


Fixes: 1d65b771 ("mm/khugepaged: retract_page_tables() without mmap or vma lock")
Signed-off-by: default avatarJann Horn <jannh@google.com>
Reviewed-by: default avatarQi Zheng <zhengqi.arch@bytedance.com>
Acked-by: default avatarDavid Hildenbrand <david@redhat.com>
Cc: Andrea Arcangeli <aarcange@redhat.com>
Cc: Hugh Dickins <hughd@google.com>
Cc: Pavel Emelyanov <xemul@virtuozzo.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Conflicts:
	mm/userfaultfd.c
[ Context conflict with userswap feature. ]
Signed-off-by: default avatarLiu Shixin <liushixin2@huawei.com>
parent 5c54320f
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -724,9 +724,10 @@ static __always_inline ssize_t mfill_atomic(struct mm_struct *dst_mm,
			err = -EFAULT;
			break;
		}

		BUG_ON(pmd_none(*dst_pmd));
		BUG_ON(pmd_trans_huge(*dst_pmd));
		/*
		 * For shmem mappings, khugepaged is allowed to remove page
		 * tables under us; pte_offset_map_lock() will deal with that.
		 */

#ifdef CONFIG_USERSWAP
		if (static_branch_unlikely(&userswap_enabled) &&