Skip to content

Commit

Permalink
[PATCH] invalidate_complete_page() race fix
Browse files Browse the repository at this point in the history
If a CPU faults this page into pagetables after invalidate_mapping_pages()
checked page_mapped(), invalidate_complete_page() will still proceed to remove
the page from pagecache.  This leaves the page-faulting process with a
detached page.  If it was MAP_SHARED then file data loss will ensue.

Fix that up by checking the page's refcount after taking tree_lock.

Cc: Nick Piggin <nickpiggin@yahoo.com.au>
Cc: Hugh Dickins <hugh@veritas.com>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
  • Loading branch information
Andrew Morton authored and Linus Torvalds committed Sep 8, 2006
1 parent 3665d0e commit 016eb4a
Showing 1 changed file with 7 additions and 4 deletions.
11 changes: 7 additions & 4 deletions mm/truncate.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,20 @@ invalidate_complete_page(struct address_space *mapping, struct page *page)
return 0;

write_lock_irq(&mapping->tree_lock);
if (PageDirty(page)) {
write_unlock_irq(&mapping->tree_lock);
return 0;
}
if (PageDirty(page))
goto failed;
if (page_count(page) != 2) /* caller's ref + pagecache ref */
goto failed;

BUG_ON(PagePrivate(page));
__remove_from_page_cache(page);
write_unlock_irq(&mapping->tree_lock);
ClearPageUptodate(page);
page_cache_release(page); /* pagecache ref */
return 1;
failed:
write_unlock_irq(&mapping->tree_lock);
return 0;
}

/**
Expand Down

0 comments on commit 016eb4a

Please sign in to comment.