Message ID | 20220727191407.1768600-1-zack@kde.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | mm: Fix a null ptr deref with CONFIG_DEBUG_VM enabled in wp_page_reuse | expand |
On Wed, Jul 27, 2022 at 03:14:07PM -0400, Zack Rusin wrote: > From: Zack Rusin <zackr@vmware.com> > > Write page faults on last references might not have a valid page anymore. > wp_page_reuse has always dealt with that scenario by making > sure the page isn't null (or the reference was shared) before doing > anything with it. Recently added checks in VM_BUG_ON (enabled by the > CONFIG_DEBUG_VM option) use PageAnon helpers which assume the passed > page is never null, before making sure there is a valid page to work > with. > > Move the VM_BUG_ON, which unconditionally uses the page, after the > code that checks that we have a valid one. Message-ID: <CAHk-=wh_TrgNm6vz7=7CgZppr0UrZ9TwLyb3dgPXyG-w=a8kJQ@mail.gmail.com>
On Wed, 2022-07-27 at 20:24 +0100, Matthew Wilcox wrote: > On Wed, Jul 27, 2022 at 03:14:07PM -0400, Zack Rusin wrote: > > From: Zack Rusin <zackr@vmware.com> > > > > Write page faults on last references might not have a valid page anymore. > > wp_page_reuse has always dealt with that scenario by making > > sure the page isn't null (or the reference was shared) before doing > > anything with it. Recently added checks in VM_BUG_ON (enabled by the > > CONFIG_DEBUG_VM option) use PageAnon helpers which assume the passed > > page is never null, before making sure there is a valid page to work > > with. > > > > Move the VM_BUG_ON, which unconditionally uses the page, after the > > code that checks that we have a valid one. > > Message-ID: <CAHk-=wh_TrgNm6vz7=7CgZppr0UrZ9TwLyb3dgPXyG-w=a8kJQ@mail.gmail.com> Ah, great, thanks. z
diff --git a/mm/memory.c b/mm/memory.c index 7a089145cad4..3e28c652cf60 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -3043,15 +3043,16 @@ static inline void wp_page_reuse(struct vm_fault *vmf) pte_t entry; VM_BUG_ON(!(vmf->flags & FAULT_FLAG_WRITE)); - VM_BUG_ON(PageAnon(page) && !PageAnonExclusive(page)); /* * Clear the pages cpupid information as the existing * information potentially belongs to a now completely * unrelated process. */ - if (page) + if (page) { + VM_BUG_ON(PageAnon(page) && !PageAnonExclusive(page)); page_cpupid_xchg_last(page, (1 << LAST_CPUPID_SHIFT) - 1); + } flush_cache_page(vma, vmf->address, pte_pfn(vmf->orig_pte)); entry = pte_mkyoung(vmf->orig_pte);