Patchwork target-arm: disable PAGE_EXEC for XN pages

login
register
mail settings
Submitter Rabin Vincent
Date March 19, 2010, 8:58 p.m.
Message ID <1269032283-2277-1-git-send-email-rabin@rab.in>
Download mbox | patch
Permalink /patch/48192/
State New
Headers show

Comments

Rabin Vincent - March 19, 2010, 8:58 p.m.
Don't set PAGE_EXEC for XN pages, to avoid a bypass of XN protection
checking if the page is already in the TLB.

Signed-off-by: Rabin Vincent <rabin@rab.in>
---
 target-arm/helper.c |   10 +++++++---
 1 files changed, 7 insertions(+), 3 deletions(-)
Aurelien Jarno - March 27, 2010, 1:15 p.m.
On Sat, Mar 20, 2010 at 02:28:03AM +0530, Rabin Vincent wrote:
> Don't set PAGE_EXEC for XN pages, to avoid a bypass of XN protection
> checking if the page is already in the TLB.

Thanks, applied.

> Signed-off-by: Rabin Vincent <rabin@rab.in>
> ---
>  target-arm/helper.c |   10 +++++++---
>  1 files changed, 7 insertions(+), 3 deletions(-)
> 
> diff --git a/target-arm/helper.c b/target-arm/helper.c
> index 18e22b1..e092b21 100644
> --- a/target-arm/helper.c
> +++ b/target-arm/helper.c
> @@ -979,6 +979,7 @@ static int get_phys_addr_v5(CPUState *env, uint32_t address, int access_type,
>          /* Access permission fault.  */
>          goto do_fault;
>      }
> +    *prot |= PAGE_EXEC;
>      *phys_ptr = phys_addr;
>      return 0;
>  do_fault:
> @@ -1075,6 +1076,9 @@ static int get_phys_addr_v6(CPUState *env, uint32_t address, int access_type,
>          /* Access permission fault.  */
>          goto do_fault;
>      }
> +    if (!xn) {
> +        *prot |= PAGE_EXEC;
> +    }
>      *phys_ptr = phys_addr;
>      return 0;
>  do_fault:
> @@ -1137,6 +1141,7 @@ static int get_phys_addr_mpu(CPUState *env, uint32_t address, int access_type,
>  	/* Bad permission.  */
>  	return 1;
>      }
> +    *prot |= PAGE_EXEC;
>      return 0;
>  }
>  
> @@ -1152,7 +1157,7 @@ static inline int get_phys_addr(CPUState *env, uint32_t address,
>      if ((env->cp15.c1_sys & 1) == 0) {
>          /* MMU/MPU disabled.  */
>          *phys_ptr = address;
> -        *prot = PAGE_READ | PAGE_WRITE;
> +        *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
>          *page_size = TARGET_PAGE_SIZE;
>          return 0;
>      } else if (arm_feature(env, ARM_FEATURE_MPU)) {
> @@ -1183,8 +1188,7 @@ int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address,
>          /* Map a single [sub]page.  */
>          phys_addr &= ~(uint32_t)0x3ff;
>          address &= ~(uint32_t)0x3ff;
> -        tlb_set_page (env, address, phys_addr, prot | PAGE_EXEC, mmu_idx,
> -                      page_size);
> +        tlb_set_page (env, address, phys_addr, prot, mmu_idx, page_size);
>          return 0;
>      }
>  
> -- 
> 1.7.0
> 
> 
> 
>

Patch

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 18e22b1..e092b21 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -979,6 +979,7 @@  static int get_phys_addr_v5(CPUState *env, uint32_t address, int access_type,
         /* Access permission fault.  */
         goto do_fault;
     }
+    *prot |= PAGE_EXEC;
     *phys_ptr = phys_addr;
     return 0;
 do_fault:
@@ -1075,6 +1076,9 @@  static int get_phys_addr_v6(CPUState *env, uint32_t address, int access_type,
         /* Access permission fault.  */
         goto do_fault;
     }
+    if (!xn) {
+        *prot |= PAGE_EXEC;
+    }
     *phys_ptr = phys_addr;
     return 0;
 do_fault:
@@ -1137,6 +1141,7 @@  static int get_phys_addr_mpu(CPUState *env, uint32_t address, int access_type,
 	/* Bad permission.  */
 	return 1;
     }
+    *prot |= PAGE_EXEC;
     return 0;
 }
 
@@ -1152,7 +1157,7 @@  static inline int get_phys_addr(CPUState *env, uint32_t address,
     if ((env->cp15.c1_sys & 1) == 0) {
         /* MMU/MPU disabled.  */
         *phys_ptr = address;
-        *prot = PAGE_READ | PAGE_WRITE;
+        *prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;
         *page_size = TARGET_PAGE_SIZE;
         return 0;
     } else if (arm_feature(env, ARM_FEATURE_MPU)) {
@@ -1183,8 +1188,7 @@  int cpu_arm_handle_mmu_fault (CPUState *env, target_ulong address,
         /* Map a single [sub]page.  */
         phys_addr &= ~(uint32_t)0x3ff;
         address &= ~(uint32_t)0x3ff;
-        tlb_set_page (env, address, phys_addr, prot | PAGE_EXEC, mmu_idx,
-                      page_size);
+        tlb_set_page (env, address, phys_addr, prot, mmu_idx, page_size);
         return 0;
     }