Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mm/uffd: fix warning without PTE_MARKER_UFFD_WP compiled in

When PTE_MARKER_UFFD_WP not configured, it's still possible to reach pte
marker code and trigger an warning. Add a few CONFIG_PTE_MARKER_UFFD_WP
ifdefs to make sure the code won't be reached when not compiled in.

Link: https://lkml.kernel.org/r/YzeR+R6b4bwBlBHh@x1n
Fixes: b1f9e876862d ("mm/uffd: enable write protection for shmem & hugetlbfs")
Signed-off-by: Peter Xu <peterx@redhat.com>
Reported-by: <syzbot+2b9b4f0895be09a6dec3@syzkaller.appspotmail.com>
Cc: Axel Rasmussen <axelrasmussen@google.com>
Cc: Brian Geffon <bgeffon@google.com>
Cc: Edward Liaw <edliaw@google.com>
Cc: Liu Shixin <liushixin2@huawei.com>
Cc: Mike Kravetz <mike.kravetz@oracle.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Peter Xu and committed by
Andrew Morton
515778e2 28c5609f

+8
+4
mm/hugetlb.c
··· 5096 5096 * unmapped and its refcount is dropped, so just clear pte here. 5097 5097 */ 5098 5098 if (unlikely(!pte_present(pte))) { 5099 + #ifdef CONFIG_PTE_MARKER_UFFD_WP 5099 5100 /* 5100 5101 * If the pte was wr-protected by uffd-wp in any of the 5101 5102 * swap forms, meanwhile the caller does not want to ··· 5108 5107 set_huge_pte_at(mm, address, ptep, 5109 5108 make_pte_marker(PTE_MARKER_UFFD_WP)); 5110 5109 else 5110 + #endif 5111 5111 huge_pte_clear(mm, address, ptep, sz); 5112 5112 spin_unlock(ptl); 5113 5113 continue; ··· 5137 5135 tlb_remove_huge_tlb_entry(h, tlb, ptep, address); 5138 5136 if (huge_pte_dirty(pte)) 5139 5137 set_page_dirty(page); 5138 + #ifdef CONFIG_PTE_MARKER_UFFD_WP 5140 5139 /* Leave a uffd-wp pte marker if needed */ 5141 5140 if (huge_pte_uffd_wp(pte) && 5142 5141 !(zap_flags & ZAP_FLAG_DROP_MARKER)) 5143 5142 set_huge_pte_at(mm, address, ptep, 5144 5143 make_pte_marker(PTE_MARKER_UFFD_WP)); 5144 + #endif 5145 5145 hugetlb_count_sub(pages_per_huge_page(h), mm); 5146 5146 page_remove_rmap(page, vma, true); 5147 5147
+2
mm/memory.c
··· 1393 1393 unsigned long addr, pte_t *pte, 1394 1394 struct zap_details *details, pte_t pteval) 1395 1395 { 1396 + #ifdef CONFIG_PTE_MARKER_UFFD_WP 1396 1397 if (zap_drop_file_uffd_wp(details)) 1397 1398 return; 1398 1399 1399 1400 pte_install_uffd_wp_if_needed(vma, addr, pte, pteval); 1401 + #endif 1400 1402 } 1401 1403 1402 1404 static unsigned long zap_pte_range(struct mmu_gather *tlb,
+2
mm/mprotect.c
··· 267 267 } else { 268 268 /* It must be an none page, or what else?.. */ 269 269 WARN_ON_ONCE(!pte_none(oldpte)); 270 + #ifdef CONFIG_PTE_MARKER_UFFD_WP 270 271 if (unlikely(uffd_wp && !vma_is_anonymous(vma))) { 271 272 /* 272 273 * For file-backed mem, we need to be able to ··· 279 278 make_pte_marker(PTE_MARKER_UFFD_WP)); 280 279 pages++; 281 280 } 281 + #endif 282 282 } 283 283 } while (pte++, addr += PAGE_SIZE, addr != end); 284 284 arch_leave_lazy_mmu_mode();