Don't enable PTE_*_CAPS to default user mappings in pgtable-prot.h. Instead, add VM_{READ,WRITE}_CAPS to all private user mappings. This ensures that the rc/wc smaps flags are set. The instances where the VM_*_CAPS flags are added by default are: - the stack and brk area by updating the VM_DATA_DEFAULT_FLAGS flags - private user mappings created by userspace through mmap()
Signed-off-by: Tudor Cretu tudor.cretu@arm.com --- arch/arm64/include/asm/mman.h | 13 +++++++++++-- arch/arm64/include/asm/page.h | 2 +- arch/arm64/include/asm/pgtable-prot.h | 12 +++++------- 3 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/arch/arm64/include/asm/mman.h b/arch/arm64/include/asm/mman.h index eb0b862121a2..88b0be497231 100644 --- a/arch/arm64/include/asm/mman.h +++ b/arch/arm64/include/asm/mman.h @@ -23,15 +23,24 @@ static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot,
static inline unsigned long arch_calc_vm_flag_bits(unsigned long flags) { + unsigned long ret = 0; + /* * Only allow MTE on anonymous mappings as these are guaranteed to be * backed by tags-capable memory. The vm_flags may be overridden by a * filesystem supporting MTE (RAM-based). */ if (system_supports_mte() && (flags & MAP_ANONYMOUS)) - return VM_MTE_ALLOWED; + ret |= VM_MTE_ALLOWED; + + /* + * Allow capability tag access to private mappings as they don't pose + * the risk of leaking capabilities outside their original address-space. + */ + if (system_supports_morello() && ((flags & MAP_TYPE) == 0x02 /* MAP_PRIVATE */)) + ret |= VM_READ_CAPS | VM_WRITE_CAPS;
- return 0; + return ret; } #define arch_calc_vm_flag_bits(flags) arch_calc_vm_flag_bits(flags)
diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h index 993a27ea6f54..1c3ed7017d86 100644 --- a/arch/arm64/include/asm/page.h +++ b/arch/arm64/include/asm/page.h @@ -47,7 +47,7 @@ int pfn_is_map_memory(unsigned long pfn);
#endif /* !__ASSEMBLY__ */
-#define VM_DATA_DEFAULT_FLAGS (VM_DATA_FLAGS_TSK_EXEC | VM_MTE_ALLOWED) +#define VM_DATA_DEFAULT_FLAGS (VM_DATA_FLAGS_TSK_EXEC | VM_MTE_ALLOWED | VM_RW_CAPS)
#include <asm-generic/getorder.h>
diff --git a/arch/arm64/include/asm/pgtable-prot.h b/arch/arm64/include/asm/pgtable-prot.h index 5463f9bc0602..ab746df170e3 100644 --- a/arch/arm64/include/asm/pgtable-prot.h +++ b/arch/arm64/include/asm/pgtable-prot.h @@ -90,11 +90,9 @@ extern bool arm64_use_ng_mappings; #define PAGE_NONE __pgprot(((_USER_PAGE_DEFAULT) & ~PTE_VALID) | PTE_PROT_NONE | PTE_RDONLY | PTE_UXN) /* shared+writable pages are clean by default, hence PTE_RDONLY|PTE_WRITE */ #define PAGE_SHARED __pgprot(_USER_PAGE_DEFAULT | PTE_RDONLY | PTE_UXN | PTE_WRITE) -#define PAGE_SHARED_RO __pgprot(_USER_PAGE_DEFAULT | PTE_RDONLY | PTE_UXN) -#define PAGE_SHARED_RO_EXEC __pgprot(_USER_PAGE_DEFAULT | PTE_RDONLY) #define PAGE_SHARED_EXEC __pgprot(_USER_PAGE_DEFAULT | PTE_RDONLY | PTE_WRITE) -#define PAGE_READONLY __pgprot(_USER_PAGE_DEFAULT | PTE_RDONLY | PTE_MAYBE_LS_CAPS | PTE_UXN) -#define PAGE_READONLY_EXEC __pgprot(_USER_PAGE_DEFAULT | PTE_RDONLY | PTE_MAYBE_LS_CAPS) +#define PAGE_READONLY __pgprot(_USER_PAGE_DEFAULT | PTE_RDONLY | PTE_UXN) +#define PAGE_READONLY_EXEC __pgprot(_USER_PAGE_DEFAULT | PTE_RDONLY) #define PAGE_EXECONLY __pgprot(_PAGE_DEFAULT | PTE_RDONLY | PTE_NG | PTE_PXN)
#define __P000 PAGE_NONE @@ -107,11 +105,11 @@ extern bool arm64_use_ng_mappings; #define __P111 PAGE_READONLY_EXEC
#define __S000 PAGE_NONE -#define __S001 PAGE_SHARED_RO +#define __S001 PAGE_READONLY #define __S010 PAGE_SHARED #define __S011 PAGE_SHARED -#define __S100 PAGE_SHARED_RO_EXEC /* PAGE_EXECONLY if Enhanced PAN */ -#define __S101 PAGE_SHARED_RO_EXEC +#define __S100 PAGE_READONLY_EXEC /* PAGE_EXECONLY if Enhanced PAN */ +#define __S101 PAGE_READONLY_EXEC #define __S110 PAGE_SHARED_EXEC #define __S111 PAGE_SHARED_EXEC