aboutsummaryrefslogtreecommitdiffstats
path: root/mm/memory.c
diff options
context:
space:
mode:
authorKirill Korotaev <dev@sw.ru>2005-05-17 00:53:50 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-05-17 10:59:20 -0400
commitb81074800b98ac50b64d4c8d34e8abf0fda5e3d1 (patch)
tree01b5114255fcf1ea8ea15fabe08cc9782131e684 /mm/memory.c
parentc64610ba585fabb36be78782868277f3d9741a2e (diff)
[PATCH] do_swap_page() can map random data if swap read fails
There is a bug in do_swap_page(): when swap page happens to be unreadable, page filled with random data is mapped into user address space. The fix is to check for PageUptodate and send SIGBUS in case of error. Signed-Off-By: Kirill Korotaev <dev@sw.ru> Signed-Off-By: Alexey Kuznetsov <kuznet@ms2.inr.ac.ru> Acked-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'mm/memory.c')
-rw-r--r--mm/memory.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/mm/memory.c b/mm/memory.c
index 6bad4c4064e7..d209f745db7f 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1701,12 +1701,13 @@ static int do_swap_page(struct mm_struct * mm,
1701 spin_lock(&mm->page_table_lock); 1701 spin_lock(&mm->page_table_lock);
1702 page_table = pte_offset_map(pmd, address); 1702 page_table = pte_offset_map(pmd, address);
1703 if (unlikely(!pte_same(*page_table, orig_pte))) { 1703 if (unlikely(!pte_same(*page_table, orig_pte))) {
1704 pte_unmap(page_table);
1705 spin_unlock(&mm->page_table_lock);
1706 unlock_page(page);
1707 page_cache_release(page);
1708 ret = VM_FAULT_MINOR; 1704 ret = VM_FAULT_MINOR;
1709 goto out; 1705 goto out_nomap;
1706 }
1707
1708 if (unlikely(!PageUptodate(page))) {
1709 ret = VM_FAULT_SIGBUS;
1710 goto out_nomap;
1710 } 1711 }
1711 1712
1712 /* The page isn't present yet, go ahead with the fault. */ 1713 /* The page isn't present yet, go ahead with the fault. */
@@ -1741,6 +1742,12 @@ static int do_swap_page(struct mm_struct * mm,
1741 spin_unlock(&mm->page_table_lock); 1742 spin_unlock(&mm->page_table_lock);
1742out: 1743out:
1743 return ret; 1744 return ret;
1745out_nomap:
1746 pte_unmap(page_table);
1747 spin_unlock(&mm->page_table_lock);
1748 unlock_page(page);
1749 page_cache_release(page);
1750 goto out;
1744} 1751}
1745 1752
1746/* 1753/*