From: Kirill Korotaev 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 Signed-Off-By: Alexey Kuznetsov Acked-by: Hugh Dickins Signed-off-by: Andrew Morton --- mm/memory.c | 17 ++++++++++++----- 1 files changed, 12 insertions(+), 5 deletions(-) diff -puN mm/memory.c~do_swap_page-can-map-random-data-if-swap-read-fails mm/memory.c --- 25/mm/memory.c~do_swap_page-can-map-random-data-if-swap-read-fails 2005-05-11 18:35:30.000000000 -0700 +++ 25-akpm/mm/memory.c 2005-05-11 18:35:30.000000000 -0700 @@ -1701,12 +1701,13 @@ static int do_swap_page(struct mm_struct spin_lock(&mm->page_table_lock); page_table = pte_offset_map(pmd, address); if (unlikely(!pte_same(*page_table, orig_pte))) { - pte_unmap(page_table); - spin_unlock(&mm->page_table_lock); - unlock_page(page); - page_cache_release(page); ret = VM_FAULT_MINOR; - goto out; + goto out_nomap; + } + + if (unlikely(!PageUptodate(page))) { + ret = VM_FAULT_SIGBUS; + goto out_nomap; } /* The page isn't present yet, go ahead with the fault. */ @@ -1741,6 +1742,12 @@ static int do_swap_page(struct mm_struct spin_unlock(&mm->page_table_lock); out: return ret; +out_nomap: + pte_unmap(page_table); + spin_unlock(&mm->page_table_lock); + unlock_page(page); + page_cache_release(page); + goto out; } /* _