Skip to content

Commit 6e2edd6

Browse files
committed
arm64: Ensure execute-only permissions are not allowed without EPAN
Commit 18107f8 ("arm64: Support execute-only permissions with Enhanced PAN") re-introduced execute-only permissions when EPAN is available. When EPAN is not available, arch_filter_pgprot() is supposed to change a PAGE_EXECONLY permission into PAGE_READONLY_EXEC. However, if BTI or MTE are present, such check does not detect the execute-only pgprot in the presence of PTE_GP (BTI) or MT_NORMAL_TAGGED (MTE), allowing the user to request PROT_EXEC with PROT_BTI or PROT_MTE. Remove the arch_filter_pgprot() function, change the default VM_EXEC permissions to PAGE_READONLY_EXEC and update the protection_map[] array at core_initcall() if EPAN is detected. Signed-off-by: Catalin Marinas <[email protected]> Fixes: 18107f8 ("arm64: Support execute-only permissions with Enhanced PAN") Cc: <[email protected]> # 5.13.x Acked-by: Will Deacon <[email protected]> Reviewed-by: Vladimir Murzin <[email protected]> Tested-by: Vladimir Murzin <[email protected]>
1 parent 4f6de67 commit 6e2edd6

File tree

4 files changed

+19
-16
lines changed

4 files changed

+19
-16
lines changed

arch/arm64/Kconfig

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,9 +1236,6 @@ config HW_PERF_EVENTS
12361236
def_bool y
12371237
depends on ARM_PMU
12381238

1239-
config ARCH_HAS_FILTER_PGPROT
1240-
def_bool y
1241-
12421239
# Supported by clang >= 7.0
12431240
config CC_HAVE_SHADOW_CALL_STACK
12441241
def_bool $(cc-option, -fsanitize=shadow-call-stack -ffixed-x18)

arch/arm64/include/asm/pgtable-prot.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ extern bool arm64_use_ng_mappings;
9292
#define __P001 PAGE_READONLY
9393
#define __P010 PAGE_READONLY
9494
#define __P011 PAGE_READONLY
95-
#define __P100 PAGE_EXECONLY
95+
#define __P100 PAGE_READONLY_EXEC /* PAGE_EXECONLY if Enhanced PAN */
9696
#define __P101 PAGE_READONLY_EXEC
9797
#define __P110 PAGE_READONLY_EXEC
9898
#define __P111 PAGE_READONLY_EXEC
@@ -101,7 +101,7 @@ extern bool arm64_use_ng_mappings;
101101
#define __S001 PAGE_READONLY
102102
#define __S010 PAGE_SHARED
103103
#define __S011 PAGE_SHARED
104-
#define __S100 PAGE_EXECONLY
104+
#define __S100 PAGE_READONLY_EXEC /* PAGE_EXECONLY if Enhanced PAN */
105105
#define __S101 PAGE_READONLY_EXEC
106106
#define __S110 PAGE_SHARED_EXEC
107107
#define __S111 PAGE_SHARED_EXEC

arch/arm64/include/asm/pgtable.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,17 +1017,6 @@ static inline bool arch_wants_old_prefaulted_pte(void)
10171017
}
10181018
#define arch_wants_old_prefaulted_pte arch_wants_old_prefaulted_pte
10191019

1020-
static inline pgprot_t arch_filter_pgprot(pgprot_t prot)
1021-
{
1022-
if (cpus_have_const_cap(ARM64_HAS_EPAN))
1023-
return prot;
1024-
1025-
if (pgprot_val(prot) != pgprot_val(PAGE_EXECONLY))
1026-
return prot;
1027-
1028-
return PAGE_READONLY_EXEC;
1029-
}
1030-
10311020
static inline bool pud_sect_supported(void)
10321021
{
10331022
return PAGE_SIZE == SZ_4K;

arch/arm64/mm/mmap.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77

88
#include <linux/io.h>
99
#include <linux/memblock.h>
10+
#include <linux/mm.h>
1011
#include <linux/types.h>
1112

13+
#include <asm/cpufeature.h>
1214
#include <asm/page.h>
1315

1416
/*
@@ -38,3 +40,18 @@ int valid_mmap_phys_addr_range(unsigned long pfn, size_t size)
3840
{
3941
return !(((pfn << PAGE_SHIFT) + size) & ~PHYS_MASK);
4042
}
43+
44+
static int __init adjust_protection_map(void)
45+
{
46+
/*
47+
* With Enhanced PAN we can honour the execute-only permissions as
48+
* there is no PAN override with such mappings.
49+
*/
50+
if (cpus_have_const_cap(ARM64_HAS_EPAN)) {
51+
protection_map[VM_EXEC] = PAGE_EXECONLY;
52+
protection_map[VM_EXEC | VM_SHARED] = PAGE_EXECONLY;
53+
}
54+
55+
return 0;
56+
}
57+
arch_initcall(adjust_protection_map);

0 commit comments

Comments
 (0)