Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c3704ceb authored by Hugh Dickins's avatar Hugh Dickins Committed by Linus Torvalds
Browse files

[PATCH] page_mkwrite caller race fix



After do_wp_page has tested page_mkwrite, it must release old_page after
acquiring page table lock, not before: at some stage that ordering got
reversed, leaving a (very unlikely) window in which old_page might be
truncated, freed, and reused in the same position.

Signed-off-by: default avatarHugh Dickins <hugh@veritas.com>
Acked-by: default avatarNick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent f05b6284
Loading
Loading
Loading
Loading
+1 −2
Original line number Original line Diff line number Diff line
@@ -1531,8 +1531,6 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
			if (vma->vm_ops->page_mkwrite(vma, old_page) < 0)
			if (vma->vm_ops->page_mkwrite(vma, old_page) < 0)
				goto unwritable_page;
				goto unwritable_page;


			page_cache_release(old_page);

			/*
			/*
			 * Since we dropped the lock we need to revalidate
			 * Since we dropped the lock we need to revalidate
			 * the PTE as someone else may have changed it.  If
			 * the PTE as someone else may have changed it.  If
@@ -1541,6 +1539,7 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
			 */
			 */
			page_table = pte_offset_map_lock(mm, pmd, address,
			page_table = pte_offset_map_lock(mm, pmd, address,
							 &ptl);
							 &ptl);
			page_cache_release(old_page);
			if (!pte_same(*page_table, orig_pte))
			if (!pte_same(*page_table, orig_pte))
				goto unlock;
				goto unlock;
		}
		}