diff mbox series

[4/5] arm64: dynamic enforcement of PXNTable

Message ID 20240416122254.868007168-5-mbland@motorola.com (mailing list archive)
State New, archived
Headers show
Series mm: code and data partitioning improvements | expand

Commit Message

Maxwell Bland April 12, 2024, 3 p.m. UTC
PXNTable is enforced during the init process to ensure that regions of
user memory and kernel data cannot be executed from, preventing attacks
which write to writable kernel pages and then modify the kernel's page
tables to make this code executable. This patch ensures this protection
is also preserved for dynamically allocated pages/pagetables, making it
so that all PMDs populated outside of the module code region are
PXNTable by default.

Signed-off-by: Maxwell Bland <mbland@motorola.com>
---
 arch/arm64/include/asm/pgalloc.h | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

Comments

kernel test robot April 17, 2024, 6:37 a.m. UTC | #1
Hi Maxwell,

kernel test robot noticed the following build errors:

[auto build test ERROR on 0bbac3facb5d6cc0171c45c9873a2dc96bea9680]

url:    https://github.com/intel-lab-lkp/linux/commits/Maxwell-Bland/mm-allow-arch-refinement-skip-for-vmap-alloc/20240417-032149
base:   0bbac3facb5d6cc0171c45c9873a2dc96bea9680
patch link:    https://lore.kernel.org/r/20240416122254.868007168-5-mbland%40motorola.com
patch subject: [PATCH 4/5 RESEND] arm64: dynamic enforcement of PXNTable
config: arm64-allnoconfig (https://download.01.org/0day-ci/archive/20240417/202404171444.fqXW3YmG-lkp@intel.com/config)
compiler: aarch64-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240417/202404171444.fqXW3YmG-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202404171444.fqXW3YmG-lkp@intel.com/

All errors (new ones prefixed by >>):

   aarch64-linux-ld: Unexpected GOT/PLT entries detected!
   aarch64-linux-ld: Unexpected run-time procedure linkages detected!
   aarch64-linux-ld: arch/arm64/kernel/setup.o: in function `setup_arch':
   setup.c:(.init.text+0x694): undefined reference to `module_init_limits'
   aarch64-linux-ld: mm/memory.o: in function `__pte_alloc_kernel':
>> memory.c:(.text+0x2b64): undefined reference to `module_plt_base'
   aarch64-linux-ld: mm/memory.o: relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol `module_plt_base' which may bind externally can not be used when making a shared object; recompile with -fPIC
   memory.c:(.text+0x2b64): dangerous relocation: unsupported relocation
>> aarch64-linux-ld: memory.c:(.text+0x2b6c): undefined reference to `module_plt_base'
>> aarch64-linux-ld: memory.c:(.text+0x2b74): undefined reference to `module_direct_base'
   aarch64-linux-ld: mm/memory.o: relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol `module_direct_base' which may bind externally can not be used when making a shared object; recompile with -fPIC
   memory.c:(.text+0x2b74): dangerous relocation: unsupported relocation
   aarch64-linux-ld: memory.c:(.text+0x2b78): undefined reference to `module_direct_base'
   aarch64-linux-ld: mm/sparse-vmemmap.o: in function `vmemmap_pmd_populate':
>> sparse-vmemmap.c:(.meminit.text+0x450): undefined reference to `module_plt_base'
   aarch64-linux-ld: mm/sparse-vmemmap.o: relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol `module_plt_base' which may bind externally can not be used when making a shared object; recompile with -fPIC
   sparse-vmemmap.c:(.meminit.text+0x450): dangerous relocation: unsupported relocation
>> aarch64-linux-ld: sparse-vmemmap.c:(.meminit.text+0x458): undefined reference to `module_plt_base'
>> aarch64-linux-ld: sparse-vmemmap.c:(.meminit.text+0x460): undefined reference to `module_direct_base'
   aarch64-linux-ld: mm/sparse-vmemmap.o: relocation R_AARCH64_ADR_PREL_PG_HI21 against symbol `module_direct_base' which may bind externally can not be used when making a shared object; recompile with -fPIC
   sparse-vmemmap.c:(.meminit.text+0x460): dangerous relocation: unsupported relocation
   aarch64-linux-ld: sparse-vmemmap.c:(.meminit.text+0x464): undefined reference to `module_direct_base'
diff mbox series

Patch

diff --git a/arch/arm64/include/asm/pgalloc.h b/arch/arm64/include/asm/pgalloc.h
index 5785272144e8..2376b4e7915c 100644
--- a/arch/arm64/include/asm/pgalloc.h
+++ b/arch/arm64/include/asm/pgalloc.h
@@ -12,6 +12,7 @@ 
 #include <asm/processor.h>
 #include <asm/cacheflush.h>
 #include <asm/tlbflush.h>
+#include <asm/module.h>
 
 #define __HAVE_ARCH_PGD_FREE
 #define __HAVE_ARCH_PUD_FREE
@@ -119,6 +120,12 @@  static inline void __pmd_populate(pmd_t *pmdp, phys_addr_t ptep,
 	set_pmd(pmdp, __pmd(__phys_to_pmd_val(ptep) | prot));
 }
 
+static inline bool vaddr_is_data(unsigned long vaddr)
+{
+	return ((vaddr + PMD_SIZE < MODULES_ASLR_START || vaddr >= MODULES_ASLR_END) &&
+		(vaddr + PMD_SIZE < (unsigned long) _text || vaddr >= (unsigned long) _etext));
+}
+
 /*
  * Populate the pmdp entry with a pointer to the pte.  This pmd is part
  * of the mm address space.
@@ -127,8 +134,11 @@  static inline void
 pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep,
 		    unsigned long vaddr)
 {
+	pmdval_t pmd = PMD_TYPE_TABLE | PMD_TABLE_UXN;
 	VM_BUG_ON(mm && mm != &init_mm);
-	__pmd_populate(pmdp, __pa(ptep), PMD_TYPE_TABLE | PMD_TABLE_UXN);
+	if (vaddr_is_data(vaddr))
+		pmd |= PMD_TABLE_PXN;
+	__pmd_populate(pmdp, __pa(ptep), pmd);
 }
 
 static inline void