Author: gber
Date: Mon May  6 15:30:34 2013
New Revision: 250297
URL: http://svnweb.freebsd.org/changeset/base/250297

Log:
  Fix L2 PTE access permissions management.
  
  Keep following access permissions:
  
  APX     AP     Kernel     User
   1      01       R         N
   1      10       R         R
   0      01      R/W        N
   0      11      R/W       R/W
  
  Avoid using reserved in ARMv6 APX|AP settings:
  - In case of unprivileged (user) access without permission to write,
    the access permission bits were being set to reserved for ARMv6
    (but valid for ARMv7) value of APX|AP = 111.
  
  Fix-up faulting userland accesses properly:
  - Wrong condition statement in pmap_fault_fixup() caused that
    any genuine, unprivileged access was being fixed-up instead of
    just skip doing anything and return. Staring from now we ensure
    proper reaction for illicit user accesses.
  
  L2_S_PROT_R and L2_S_PROT_U names might be misleading as they do not
  reflect real permission levels. It will be clarified in following
  patches (switch to AP[2:1] permissions model).
  
  Obtained from: Semihalf

Modified:
  head/sys/arm/arm/pmap-v6.c
  head/sys/arm/include/pmap.h

Modified: head/sys/arm/arm/pmap-v6.c
==============================================================================
--- head/sys/arm/arm/pmap-v6.c  Mon May  6 14:57:02 2013        (r250296)
+++ head/sys/arm/arm/pmap-v6.c  Mon May  6 15:30:34 2013        (r250297)
@@ -983,6 +983,7 @@ pmap_set_prot(pt_entry_t *ptep, vm_prot_
        if (!(prot & VM_PROT_EXECUTE))
                *ptep |= L2_XN;
 
+       *ptep |= L2_APX;
        *ptep |= L2_S_PROT_R;
 
        if (user)
@@ -990,6 +991,8 @@ pmap_set_prot(pt_entry_t *ptep, vm_prot_
 
        if (prot & VM_PROT_WRITE)
                *ptep &= ~(L2_APX);
+       else if (user)
+               *ptep &= ~(L2_S_PROT_R);
 }
 
 /*
@@ -1216,7 +1219,7 @@ pmap_fault_fixup(pmap_t pm, vm_offset_t 
        /*
         * Catch a userland access to the vector page mapped at 0x0
         */
-       if (user && ((pte & L2_S_PROT_MASK) == L2_S_PROT_U))
+       if (user && !(pte & L2_S_PROT_U))
                goto out;
        if (va == vector_page)
                goto out;
@@ -2649,7 +2652,10 @@ do_l2b_alloc:
                npte |= L2_TYPE_INV;
        }
 
+       npte |= L2_APX;
        npte |= L2_S_PROT_R;
+       if (user)
+               npte |= L2_S_PROT_U;
 
        if (prot & VM_PROT_WRITE) {
                npte &= ~(L2_APX);
@@ -2657,11 +2663,8 @@ do_l2b_alloc:
                if (m != NULL &&
                    (m->oflags & VPO_UNMANAGED) == 0)
                        vm_page_aflag_set(m, PGA_WRITEABLE);
-       }
-
-       if (user)
-               npte |= L2_S_PROT_U;
-
+       } else if (user)
+               npte &= ~(L2_S_PROT_R);
 
        if (!(prot & VM_PROT_EXECUTE) && m)
                npte |= L2_XN;

Modified: head/sys/arm/include/pmap.h
==============================================================================
--- head/sys/arm/include/pmap.h Mon May  6 14:57:02 2013        (r250296)
+++ head/sys/arm/include/pmap.h Mon May  6 15:30:34 2013        (r250297)
@@ -352,7 +352,7 @@ extern int pmap_needs_pte_sync;
 #elif (ARM_MMU_V6 + ARM_MMU_V7) != 0
 
 #define        L2_S_PROT_U             (L2_AP0(2))             /* user access 
*/
-#define        L2_S_PROT_R             (L2_APX|L2_AP0(1))      /* read access 
*/
+#define        L2_S_PROT_R             (L2_AP0(1))             /* read access 
*/
 
 #define        L2_S_PROT_MASK          (L2_S_PROT_U|L2_S_PROT_R)
 #define        L2_S_WRITABLE(pte)      (!(pte & L2_APX))
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to