From: Paolo 'Blaisorblade' Giarrusso <[email protected]>, Ingo Molnar <[email protected]>
This patch may or may not be wanted. I took this from the original Ingo's
patch and improved it, but probably we want to keep this bug. However, I'm not
sure of what Ingo wanted to do.
If on a private writable mapping we call remap_file_pages() without
altering the file offset or the protections, after writing on the page to
create a COW mapping, with this patch we refuse reinstalling the old page, as
we should.
However, I'm not sure there's a point for an app to do this.
It is possible that we return an error even if the present page is already the
same one; however, that shouldn't be a big problem. In fact, the main purpose
of supporting private VMAs in remap_file_pages is allowing mmap(MAP_PRIVATE |
MAP_POPULATE) to work, and for that case existing mappings have already been
cleared and this patch is unneeded.
Note that this patch *needs* testing on each existing arch - I already got
subtle failures on i386 and not on UML on this patch (I had forgot to test
pte_present(), and pte_file() returned true, because _PAGE_DIRTY and
_PAGE_FILE share the same slot).
Setting CONFIG_DEBUG_PRIVATE in the test-program provides a mean to test this.
Signed-off-by: Paolo 'Blaisorblade' Giarrusso <[email protected]>
---
linux-2.6.git-paolo/mm/fremap.c | 19 +++++++++++++++++++
1 files changed, 19 insertions(+)
diff -puN mm/fremap.c~rfp-notrunc-priv-mappings mm/fremap.c
--- linux-2.6.git/mm/fremap.c~rfp-notrunc-priv-mappings 2005-08-24 20:57:34.000000000 +0200
+++ linux-2.6.git-paolo/mm/fremap.c 2005-08-24 20:57:34.000000000 +0200
@@ -94,6 +94,16 @@ int install_page(struct mm_struct *mm, s
if (!page->mapping || page->index >= size)
goto err_unlock;
+ /*
+ * On private (and thus uniform) mapping, we don't want to truncate COW
+ * page, so we can only override pte_none or pte_file PTEs, not swap or
+ * present ones.
+ */
+ err = -EEXIST;
+ if (unlikely(!(vma->vm_flags & VM_SHARED)) && (pte_present(*pte) ||
+ (!pte_none(*pte) && !pte_file(*pte))))
+ goto err_unlock;
+
zap_pte(mm, vma, addr, pte);
inc_mm_counter(mm,rss);
@@ -155,6 +165,15 @@ int install_file_pte(struct mm_struct *m
err = 0;
if (uniform && pte_none(*pte))
goto err_unlock;
+ /*
+ * On private (and thus uniform) mapping, we don't want to truncate COW
+ * page, so we can only override pte_none or pte_file PTEs, not swap or
+ * present ones.
+ */
+ err = -EEXIST;
+ if (unlikely(!(vma->vm_flags & VM_SHARED)) && (pte_present(*pte) ||
+ (!pte_none(*pte) && !pte_file(*pte))))
+ goto err_unlock;
err = 0;
zap_pte(mm, vma, addr, pte);
_
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
|
|