[patch 33/39] remap_file_pages protection support: VM_FAULT_SIGSEGV permission checking rework

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Paolo 'Blaisorblade' Giarrusso <[email protected]>

Simplify the generic arch permission checking: the previous one was clumsy, as
it didn't account arch-specific implications (read implies exec, write implies
read, and so on).

Still to undo fixes for the archs (i386 and UML) which were modified for the
previous scheme.

Signed-off-by: Paolo 'Blaisorblade' Giarrusso <[email protected]>
---

 linux-2.6.git-paolo/mm/memory.c |   49 ++++++++++++++++++++++++++--------------
 1 files changed, 33 insertions(+), 16 deletions(-)

diff -puN mm/memory.c~rfp-sigsegv-4 mm/memory.c
--- linux-2.6.git/mm/memory.c~rfp-sigsegv-4	2005-08-12 17:18:55.000000000 +0200
+++ linux-2.6.git-paolo/mm/memory.c	2005-08-12 17:18:55.000000000 +0200
@@ -1923,6 +1923,35 @@ oom:
 	goto out;
 }
 
+static inline int check_perms(struct vm_area_struct * vma, int access_mask) {
+	if (unlikely(vm_flags & VM_NONUNIFORM)) {
+		/* we used to check protections in arch handler, but with
+		 * VM_NONUNIFORM the check is skipped. */
+#if 0
+		if ((access_mask & VM_WRITE) > (vm_flags & VM_WRITE))
+			goto err;
+		if ((access_mask & VM_READ) > (vm_flags & VM_READ))
+			goto err;
+		if ((access_mask & VM_EXEC) > (vm_flags & VM_EXEC))
+			goto err;
+#else
+		/* access_mask contains the type of the access, vm_flags are the
+		 * declared protections, pte has the protection which will be
+		 * given to the PTE's in that area. */
+		//pte_t pte = pfn_pte(0UL, protection_map[vm_flags & 0x0f|VM_SHARED]);
+		pte_t pte = pfn_pte(0UL, vma->vm_page_prot);
+		if ((access_mask & VM_WRITE) && ! pte_write(pte))
+			goto err;
+		if ((access_mask & VM_READ) && ! pte_read(pte))
+			goto err;
+		if ((access_mask & VM_EXEC) && ! pte_exec(pte))
+			goto err;
+#endif
+	}
+	return 0;
+err:
+	return -EPERM;
+}
 /*
  * Fault of a previously existing named mapping. Repopulate the pte
  * from the encoded file_pte if possible. This enables swappable
@@ -1944,14 +1973,8 @@ static int do_file_page(struct mm_struct
 			((access_mask & VM_WRITE) && !(vma->vm_flags & VM_SHARED))) {
 		/* We're behaving as if pte_file was cleared, so check
 		 * protections like in handle_pte_fault. */
-		if (unlikely(vma->vm_flags & VM_NONUNIFORM)) {
-			if ((access_mask & VM_WRITE) > (vma->vm_flags & VM_WRITE))
-				goto out_segv;
-			if ((access_mask & VM_READ) > (vma->vm_flags & VM_READ))
-				goto out_segv;
-			if ((access_mask & VM_EXEC) > (vma->vm_flags & VM_EXEC))
-				goto out_segv;
-		}
+		if (check_perms(vma, access_mask))
+			goto out_segv;
 
 		pte_clear(mm, address, pte);
 		return do_no_page(mm, vma, address, access_mask & VM_WRITE, pte, pmd);
@@ -2007,14 +2030,8 @@ static inline int handle_pte_fault(struc
 		/* when pte_file(), the VMA protections are useless. Otherwise,
 		 * we used to check protections in arch handler, but with
 		 * VM_NONUNIFORM the check is skipped. */
-		if (unlikely(vma->vm_flags & VM_NONUNIFORM) && !pte_file(entry)) {
-			if ((access_mask & VM_WRITE) > (vma->vm_flags & VM_WRITE))
-				goto out_segv;
-			if ((access_mask & VM_READ) > (vma->vm_flags & VM_READ))
-				goto out_segv;
-			if ((access_mask & VM_EXEC) > (vma->vm_flags & VM_EXEC))
-				goto out_segv;
-		}
+		if (!pte_file(entry) && check_perms(vma, access_mask))
+			goto out_segv;
 
 		/*
 		 * If it truly wasn't present, we know that kswapd
_
-
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]
  Powered by Linux