-
Andrew Morton authored
From: Hugh Dickins <hugh@veritas.com> Fixes bugzilla #2219 fork's dup_mmap leaves child mm_rb as copied from parent mm while doing all the copy_page_ranges, and then calls build_mmap_rb without holding page_table_lock. try_to_unmap_one's find_vma (holding page_table_lock not mmap_sem) coming on another cpu may cause mm mayhem. It may leave the child's mmap_cache pointing to a vma of the parent mm. When the parent exits and the child faults, quite what happens rather depends on what junk then inhabits vm_page_prot, which gets set in the page table, with page_add_rmap adding the ptep, but junk pte likely to fail the tests for page_remove_rmap. Eventually the child exits, the page table is freed and try_to_unmap_one oopses on null ptep_to_mm (but in a kernel with rss limiting, usually page_referenced hits the null ptep_to_mm first). This took me days and days to unravel! Big thanks to Matthieu for reporting it with a good test case.
bc3d0059