linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] Refactor CONFIG_DEBUG_WX and check_wx_pages debugfs attribute
@ 2024-01-09 12:14 Christophe Leroy
  2024-01-09 12:14 ` [PATCH 1/4] arm: ptdump: Rename CONFIG_DEBUG_WX to CONFIG_ARM_DEBUG_WX Christophe Leroy
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Christophe Leroy @ 2024-01-09 12:14 UTC (permalink / raw)
  To: linux-hardening, Russell King, Catalin Marinas, Will Deacon,
	Michael Ellerman, Nicholas Piggin, Aneesh Kumar K.V,
	Naveen N. Rao, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Andrew Morton,
	Kees Cook
  Cc: Christophe Leroy, linux-arm-kernel, linux-kernel, linuxppc-dev,
	linux-riscv, linux-s390, linux-mm, steven.price, Phong Tran,
	mark.rutland, Greg KH

Refer old discussion at https://lore.kernel.org/lkml/20200422152656.GF676@willie-the-truck/T/#m802eaf33efd6f8d575939d157301b35ac0d4a64f
And https://github.com/KSPP/linux/issues/35

This series refactors CONFIG_DEBUG_WX for the 5 architectures
implementing CONFIG_GENERIC_PTDUMP

First rename stuff in ARM which uses similar names while not
implementing CONFIG_GENERIC_PTDUMP.

Then define a generic version of debug_checkwx() that calls
ptdump_check_wx() when CONFIG_DEBUG_WX is set. Call it immediately
after calling mark_rodata_ro() instead of calling it at the end of
every mark_rodata_ro().

Then implement a debugfs attribute that can be used to trigger
a W^X test at anytime and regardless of CONFIG_DEBUG_WX

Christophe Leroy (4):
  arm: ptdump: Rename CONFIG_DEBUG_WX to CONFIG_ARM_DEBUG_WX
  arm64, powerpc, riscv, s390, x86: Refactor CONFIG_DEBUG_WX
  powerpc,s390: Define ptdump_check_wx() regardless of CONFIG_DEBUG_WX
  ptdump: add check_wx_pages debugfs attribute

 arch/arm/Kconfig.debug          |  2 +-
 arch/arm/include/asm/ptdump.h   |  6 +++---
 arch/arm64/include/asm/ptdump.h |  7 -------
 arch/arm64/mm/mmu.c             |  2 --
 arch/powerpc/mm/mmu_decl.h      |  6 ------
 arch/powerpc/mm/pgtable_32.c    |  4 ----
 arch/powerpc/mm/pgtable_64.c    |  3 ---
 arch/powerpc/mm/ptdump/ptdump.c | 10 ++++++----
 arch/riscv/include/asm/ptdump.h | 22 ----------------------
 arch/riscv/mm/init.c            |  3 ---
 arch/riscv/mm/ptdump.c          |  1 -
 arch/s390/include/asm/ptdump.h  | 14 --------------
 arch/s390/mm/dump_pagetables.c  |  8 ++------
 arch/s390/mm/init.c             |  2 --
 arch/x86/include/asm/pgtable.h  |  3 +--
 arch/x86/mm/dump_pagetables.c   |  3 +++
 arch/x86/mm/init_32.c           |  2 --
 arch/x86/mm/init_64.c           |  2 --
 include/linux/ptdump.h          |  7 +++++++
 init/main.c                     |  2 ++
 mm/ptdump.c                     | 19 +++++++++++++++++++
 21 files changed, 44 insertions(+), 84 deletions(-)
 delete mode 100644 arch/riscv/include/asm/ptdump.h
 delete mode 100644 arch/s390/include/asm/ptdump.h

-- 
2.41.0


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/4] arm: ptdump: Rename CONFIG_DEBUG_WX to CONFIG_ARM_DEBUG_WX
  2024-01-09 12:14 [PATCH 0/4] Refactor CONFIG_DEBUG_WX and check_wx_pages debugfs attribute Christophe Leroy
@ 2024-01-09 12:14 ` Christophe Leroy
  2024-01-09 17:09   ` Florian Fainelli
  2024-01-09 12:14 ` [PATCH 2/4] arm64, powerpc, riscv, s390, x86: Refactor CONFIG_DEBUG_WX Christophe Leroy
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Christophe Leroy @ 2024-01-09 12:14 UTC (permalink / raw)
  To: linux-hardening, Russell King, Catalin Marinas, Will Deacon,
	Michael Ellerman, Nicholas Piggin, Aneesh Kumar K.V,
	Naveen N. Rao, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Andrew Morton,
	Kees Cook
  Cc: Christophe Leroy, linux-arm-kernel, linux-kernel, linuxppc-dev,
	linux-riscv, linux-s390, linux-mm, steven.price, Phong Tran,
	mark.rutland, Greg KH

CONFIG_DEBUG_WX is a core option defined in mm/Kconfig.debug

To avoid any future conflict, rename ARM version
into CONFIG_ARM_DEBUG_WX.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/arm/Kconfig.debug        | 2 +-
 arch/arm/include/asm/ptdump.h | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index fc2b41d41447..141151d632f6 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -17,7 +17,7 @@ config ARM_PTDUMP_DEBUGFS
 	  kernel.
 	  If in doubt, say "N"
 
-config DEBUG_WX
+config ARM_DEBUG_WX
 	bool "Warn on W+X mappings at boot"
 	depends on MMU
 	select ARM_PTDUMP_CORE
diff --git a/arch/arm/include/asm/ptdump.h b/arch/arm/include/asm/ptdump.h
index aad1d034136c..46a4575146ee 100644
--- a/arch/arm/include/asm/ptdump.h
+++ b/arch/arm/include/asm/ptdump.h
@@ -32,10 +32,10 @@ void ptdump_check_wx(void);
 
 #endif /* CONFIG_ARM_PTDUMP_CORE */
 
-#ifdef CONFIG_DEBUG_WX
-#define debug_checkwx() ptdump_check_wx()
+#ifdef CONFIG_ARM_DEBUG_WX
+#define arm_debug_checkwx() ptdump_check_wx()
 #else
-#define debug_checkwx() do { } while (0)
+#define arm_debug_checkwx() do { } while (0)
 #endif
 
 #endif /* __ASM_PTDUMP_H */
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/4] arm64, powerpc, riscv, s390, x86: Refactor CONFIG_DEBUG_WX
  2024-01-09 12:14 [PATCH 0/4] Refactor CONFIG_DEBUG_WX and check_wx_pages debugfs attribute Christophe Leroy
  2024-01-09 12:14 ` [PATCH 1/4] arm: ptdump: Rename CONFIG_DEBUG_WX to CONFIG_ARM_DEBUG_WX Christophe Leroy
@ 2024-01-09 12:14 ` Christophe Leroy
  2024-01-09 12:54   ` Alexandre Ghiti
  2024-01-09 12:14 ` [PATCH 3/4] powerpc,s390: Define ptdump_check_wx() regardless of CONFIG_DEBUG_WX Christophe Leroy
  2024-01-09 12:14 ` [PATCH 4/4] ptdump: add check_wx_pages debugfs attribute Christophe Leroy
  3 siblings, 1 reply; 8+ messages in thread
From: Christophe Leroy @ 2024-01-09 12:14 UTC (permalink / raw)
  To: linux-hardening, Russell King, Catalin Marinas, Will Deacon,
	Michael Ellerman, Nicholas Piggin, Aneesh Kumar K.V,
	Naveen N. Rao, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Andrew Morton,
	Kees Cook
  Cc: Christophe Leroy, linux-arm-kernel, linux-kernel, linuxppc-dev,
	linux-riscv, linux-s390, linux-mm, steven.price, Phong Tran,
	mark.rutland, Greg KH

All architectures using the core ptdump functionality also implement
CONFIG_DEBUG_WX, and they all do it more or less the same way, with a
function called debug_checkwx() that is called by mark_rodata_ro(),
which is a substitute to ptdump_check_wx() when CONFIG_DEBUG_WX is
set and a no-op otherwise.

Refactor by centraly defining debug_checkwx() in linux/ptdump.h and
call debug_checkwx() immediately after calling mark_rodata_ro()
instead of calling it at the end of every mark_rodata_ro().

On x86_32, mark_rodata_ro() first checks __supported_pte_mask has
_PAGE_NX before calling debug_checkwx(). Now the check is inside the
callee ptdump_walk_pgd_level_checkwx().

On powerpc_64, mark_rodata_ro() bails out early before calling
ptdump_check_wx() when the MMU doesn't have KERNEL_RO feature. The
check is now also done in ptdump_check_wx() as it is called outside
mark_rodata_ro().

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/arm64/include/asm/ptdump.h |  7 -------
 arch/arm64/mm/mmu.c             |  2 --
 arch/powerpc/mm/mmu_decl.h      |  6 ------
 arch/powerpc/mm/pgtable_32.c    |  4 ----
 arch/powerpc/mm/pgtable_64.c    |  3 ---
 arch/powerpc/mm/ptdump/ptdump.c |  3 +++
 arch/riscv/include/asm/ptdump.h | 22 ----------------------
 arch/riscv/mm/init.c            |  3 ---
 arch/riscv/mm/ptdump.c          |  1 -
 arch/s390/include/asm/ptdump.h  | 14 --------------
 arch/s390/mm/dump_pagetables.c  |  1 -
 arch/s390/mm/init.c             |  2 --
 arch/x86/include/asm/pgtable.h  |  3 +--
 arch/x86/mm/dump_pagetables.c   |  3 +++
 arch/x86/mm/init_32.c           |  2 --
 arch/x86/mm/init_64.c           |  2 --
 include/linux/ptdump.h          |  7 +++++++
 init/main.c                     |  2 ++
 18 files changed, 16 insertions(+), 71 deletions(-)
 delete mode 100644 arch/riscv/include/asm/ptdump.h
 delete mode 100644 arch/s390/include/asm/ptdump.h

diff --git a/arch/arm64/include/asm/ptdump.h b/arch/arm64/include/asm/ptdump.h
index 581caac525b0..5b1701c76d1c 100644
--- a/arch/arm64/include/asm/ptdump.h
+++ b/arch/arm64/include/asm/ptdump.h
@@ -29,13 +29,6 @@ void __init ptdump_debugfs_register(struct ptdump_info *info, const char *name);
 static inline void ptdump_debugfs_register(struct ptdump_info *info,
 					   const char *name) { }
 #endif
-void ptdump_check_wx(void);
 #endif /* CONFIG_PTDUMP_CORE */
 
-#ifdef CONFIG_DEBUG_WX
-#define debug_checkwx()	ptdump_check_wx()
-#else
-#define debug_checkwx()	do { } while (0)
-#endif
-
 #endif /* __ASM_PTDUMP_H */
diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
index 15f6347d23b6..e011beb2e5e3 100644
--- a/arch/arm64/mm/mmu.c
+++ b/arch/arm64/mm/mmu.c
@@ -635,8 +635,6 @@ void mark_rodata_ro(void)
 	section_size = (unsigned long)__init_begin - (unsigned long)__start_rodata;
 	update_mapping_prot(__pa_symbol(__start_rodata), (unsigned long)__start_rodata,
 			    section_size, PAGE_KERNEL_RO);
-
-	debug_checkwx();
 }
 
 static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end,
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 72341b9fb552..90dcc2844056 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -171,12 +171,6 @@ static inline void mmu_mark_rodata_ro(void) { }
 void __init mmu_mapin_immr(void);
 #endif
 
-#ifdef CONFIG_DEBUG_WX
-void ptdump_check_wx(void);
-#else
-static inline void ptdump_check_wx(void) { }
-#endif
-
 static inline bool debug_pagealloc_enabled_or_kfence(void)
 {
 	return IS_ENABLED(CONFIG_KFENCE) || debug_pagealloc_enabled();
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 5c02fd08d61e..12498017da8e 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -153,7 +153,6 @@ void mark_rodata_ro(void)
 
 	if (v_block_mapped((unsigned long)_stext + 1)) {
 		mmu_mark_rodata_ro();
-		ptdump_check_wx();
 		return;
 	}
 
@@ -166,9 +165,6 @@ void mark_rodata_ro(void)
 		   PFN_DOWN((unsigned long)_stext);
 
 	set_memory_ro((unsigned long)_stext, numpages);
-
-	// mark_initmem_nx() should have already run by now
-	ptdump_check_wx();
 }
 #endif
 
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 5ac1fd30341b..1b366526f4f2 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -150,9 +150,6 @@ void mark_rodata_ro(void)
 		radix__mark_rodata_ro();
 	else
 		hash__mark_rodata_ro();
-
-	// mark_initmem_nx() should have already run by now
-	ptdump_check_wx();
 }
 
 void mark_initmem_nx(void)
diff --git a/arch/powerpc/mm/ptdump/ptdump.c b/arch/powerpc/mm/ptdump/ptdump.c
index 2313053fe679..620d4917ebe8 100644
--- a/arch/powerpc/mm/ptdump/ptdump.c
+++ b/arch/powerpc/mm/ptdump/ptdump.c
@@ -343,6 +343,9 @@ void ptdump_check_wx(void)
 		}
 	};
 
+	if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && !mmu_has_feature(MMU_FTR_KERNEL_RO))
+		return;
+
 	ptdump_walk_pgd(&st.ptdump, &init_mm, NULL);
 
 	if (st.wx_pages)
diff --git a/arch/riscv/include/asm/ptdump.h b/arch/riscv/include/asm/ptdump.h
deleted file mode 100644
index 3c9ea6dd5af7..000000000000
--- a/arch/riscv/include/asm/ptdump.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-/*
- * Copyright (C) 2019 SiFive
- */
-
-#ifndef _ASM_RISCV_PTDUMP_H
-#define _ASM_RISCV_PTDUMP_H
-
-void ptdump_check_wx(void);
-
-#ifdef CONFIG_DEBUG_WX
-static inline void debug_checkwx(void)
-{
-	ptdump_check_wx();
-}
-#else
-static inline void debug_checkwx(void)
-{
-}
-#endif
-
-#endif /* _ASM_RISCV_PTDUMP_H */
diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 2e011cbddf3a..55c4deb1b332 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -29,7 +29,6 @@
 #include <asm/io.h>
 #include <asm/numa.h>
 #include <asm/pgtable.h>
-#include <asm/ptdump.h>
 #include <asm/sections.h>
 #include <asm/soc.h>
 #include <asm/tlbflush.h>
@@ -720,8 +719,6 @@ void mark_rodata_ro(void)
 	if (IS_ENABLED(CONFIG_64BIT))
 		set_kernel_memory(lm_alias(__start_rodata), lm_alias(_data),
 				  set_memory_ro);
-
-	debug_checkwx();
 }
 #else
 static __init pgprot_t pgprot_from_va(uintptr_t va)
diff --git a/arch/riscv/mm/ptdump.c b/arch/riscv/mm/ptdump.c
index 657c27bc07a7..075265603313 100644
--- a/arch/riscv/mm/ptdump.c
+++ b/arch/riscv/mm/ptdump.c
@@ -9,7 +9,6 @@
 #include <linux/seq_file.h>
 #include <linux/ptdump.h>
 
-#include <asm/ptdump.h>
 #include <linux/pgtable.h>
 #include <asm/kasan.h>
 
diff --git a/arch/s390/include/asm/ptdump.h b/arch/s390/include/asm/ptdump.h
deleted file mode 100644
index f960b2896606..000000000000
--- a/arch/s390/include/asm/ptdump.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-
-#ifndef _ASM_S390_PTDUMP_H
-#define _ASM_S390_PTDUMP_H
-
-void ptdump_check_wx(void);
-
-static inline void debug_checkwx(void)
-{
-	if (IS_ENABLED(CONFIG_DEBUG_WX))
-		ptdump_check_wx();
-}
-
-#endif /* _ASM_S390_PTDUMP_H */
diff --git a/arch/s390/mm/dump_pagetables.c b/arch/s390/mm/dump_pagetables.c
index d37a8f607b71..8dcb4e0c71bd 100644
--- a/arch/s390/mm/dump_pagetables.c
+++ b/arch/s390/mm/dump_pagetables.c
@@ -6,7 +6,6 @@
 #include <linux/mm.h>
 #include <linux/kfence.h>
 #include <linux/kasan.h>
-#include <asm/ptdump.h>
 #include <asm/kasan.h>
 #include <asm/abs_lowcore.h>
 #include <asm/nospec-branch.h>
diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
index 43e612bc2bcd..d2e5eff9d1de 100644
--- a/arch/s390/mm/init.c
+++ b/arch/s390/mm/init.c
@@ -37,7 +37,6 @@
 #include <asm/pgalloc.h>
 #include <asm/ctlreg.h>
 #include <asm/kfence.h>
-#include <asm/ptdump.h>
 #include <asm/dma.h>
 #include <asm/abs_lowcore.h>
 #include <asm/tlb.h>
@@ -109,7 +108,6 @@ void mark_rodata_ro(void)
 
 	__set_memory_ro(__start_ro_after_init, __end_ro_after_init);
 	pr_info("Write protected read-only-after-init data: %luk\n", size >> 10);
-	debug_checkwx();
 }
 
 int set_memory_encrypted(unsigned long vaddr, int numpages)
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 57bab91bbf50..036ce63f3b95 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -32,6 +32,7 @@ void ptdump_walk_pgd_level(struct seq_file *m, struct mm_struct *mm);
 void ptdump_walk_pgd_level_debugfs(struct seq_file *m, struct mm_struct *mm,
 				   bool user);
 void ptdump_walk_pgd_level_checkwx(void);
+#define ptdump_check_wx() ptdump_walk_pgd_level_checkwx()
 void ptdump_walk_user_pgd_level_checkwx(void);
 
 /*
@@ -41,10 +42,8 @@ void ptdump_walk_user_pgd_level_checkwx(void);
 #define pgprot_decrypted(prot)	__pgprot(cc_mkdec(pgprot_val(prot)))
 
 #ifdef CONFIG_DEBUG_WX
-#define debug_checkwx()		ptdump_walk_pgd_level_checkwx()
 #define debug_checkwx_user()	ptdump_walk_user_pgd_level_checkwx()
 #else
-#define debug_checkwx()		do { } while (0)
 #define debug_checkwx_user()	do { } while (0)
 #endif
 
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
index e1b599ecbbc2..0008524eebe9 100644
--- a/arch/x86/mm/dump_pagetables.c
+++ b/arch/x86/mm/dump_pagetables.c
@@ -433,6 +433,9 @@ void ptdump_walk_user_pgd_level_checkwx(void)
 
 void ptdump_walk_pgd_level_checkwx(void)
 {
+	if (!(__supported_pte_mask & _PAGE_NX))
+		return;
+
 	ptdump_walk_pgd_level_core(NULL, &init_mm, INIT_PGD, true, false);
 }
 
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index b63403d7179d..5c736b707cae 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -800,6 +800,4 @@ void mark_rodata_ro(void)
 	set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
 #endif
 	mark_nxdata_nx();
-	if (__supported_pte_mask & _PAGE_NX)
-		debug_checkwx();
 }
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index a190aae8ceaf..16e248769338 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -1412,8 +1412,6 @@ void mark_rodata_ro(void)
 				(void *)text_end, (void *)rodata_start);
 	free_kernel_image_pages("unused kernel image (rodata/data gap)",
 				(void *)rodata_end, (void *)_sdata);
-
-	debug_checkwx();
 }
 
 /*
diff --git a/include/linux/ptdump.h b/include/linux/ptdump.h
index 2a3a95586425..c10513739bf9 100644
--- a/include/linux/ptdump.h
+++ b/include/linux/ptdump.h
@@ -19,5 +19,12 @@ struct ptdump_state {
 };
 
 void ptdump_walk_pgd(struct ptdump_state *st, struct mm_struct *mm, pgd_t *pgd);
+void ptdump_check_wx(void);
+
+static inline void debug_checkwx(void)
+{
+	if (IS_ENABLED(CONFIG_DEBUG_WX))
+		ptdump_check_wx();
+}
 
 #endif /* _LINUX_PTDUMP_H */
diff --git a/init/main.c b/init/main.c
index e24b0780fdff..749a9f8d2c9b 100644
--- a/init/main.c
+++ b/init/main.c
@@ -99,6 +99,7 @@
 #include <linux/init_syscalls.h>
 #include <linux/stackdepot.h>
 #include <linux/randomize_kstack.h>
+#include <linux/ptdump.h>
 #include <net/net_namespace.h>
 
 #include <asm/io.h>
@@ -1408,6 +1409,7 @@ static void mark_readonly(void)
 		 */
 		rcu_barrier();
 		mark_rodata_ro();
+		debug_checkwx();
 		rodata_test();
 	} else
 		pr_info("Kernel memory protection disabled.\n");
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/4] powerpc,s390: Define ptdump_check_wx() regardless of CONFIG_DEBUG_WX
  2024-01-09 12:14 [PATCH 0/4] Refactor CONFIG_DEBUG_WX and check_wx_pages debugfs attribute Christophe Leroy
  2024-01-09 12:14 ` [PATCH 1/4] arm: ptdump: Rename CONFIG_DEBUG_WX to CONFIG_ARM_DEBUG_WX Christophe Leroy
  2024-01-09 12:14 ` [PATCH 2/4] arm64, powerpc, riscv, s390, x86: Refactor CONFIG_DEBUG_WX Christophe Leroy
@ 2024-01-09 12:14 ` Christophe Leroy
  2024-01-09 12:14 ` [PATCH 4/4] ptdump: add check_wx_pages debugfs attribute Christophe Leroy
  3 siblings, 0 replies; 8+ messages in thread
From: Christophe Leroy @ 2024-01-09 12:14 UTC (permalink / raw)
  To: linux-hardening, Russell King, Catalin Marinas, Will Deacon,
	Michael Ellerman, Nicholas Piggin, Aneesh Kumar K.V,
	Naveen N. Rao, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Andrew Morton,
	Kees Cook
  Cc: Christophe Leroy, linux-arm-kernel, linux-kernel, linuxppc-dev,
	linux-riscv, linux-s390, linux-mm, steven.price, Phong Tran,
	mark.rutland, Greg KH

Following patch will use ptdump_check_wx() regardless of
CONFIG_DEBUG_WX, so define it at all times of powerpc and s390
just like other architectures. Though keep the WARN_ON_ONCE()
only when CONFIG_DEBUG_WX is set.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 arch/powerpc/mm/ptdump/ptdump.c | 7 +++----
 arch/s390/mm/dump_pagetables.c  | 7 ++-----
 2 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/arch/powerpc/mm/ptdump/ptdump.c b/arch/powerpc/mm/ptdump/ptdump.c
index 620d4917ebe8..b835c80371cd 100644
--- a/arch/powerpc/mm/ptdump/ptdump.c
+++ b/arch/powerpc/mm/ptdump/ptdump.c
@@ -184,13 +184,14 @@ static void note_prot_wx(struct pg_state *st, unsigned long addr)
 {
 	pte_t pte = __pte(st->current_flags);
 
-	if (!IS_ENABLED(CONFIG_DEBUG_WX) || !st->check_wx)
+	if (!st->check_wx)
 		return;
 
 	if (!pte_write(pte) || !pte_exec(pte))
 		return;
 
-	WARN_ONCE(1, "powerpc/mm: Found insecure W+X mapping at address %p/%pS\n",
+	WARN_ONCE(IS_ENABLED(CONFIG_DEBUG_WX),
+		  "powerpc/mm: Found insecure W+X mapping at address %p/%pS\n",
 		  (void *)st->start_address, (void *)st->start_address);
 
 	st->wx_pages += (addr - st->start_address) / PAGE_SIZE;
@@ -326,7 +327,6 @@ static void __init build_pgtable_complete_mask(void)
 				pg_level[i].mask |= pg_level[i].flag[j].mask;
 }
 
-#ifdef CONFIG_DEBUG_WX
 void ptdump_check_wx(void)
 {
 	struct pg_state st = {
@@ -354,7 +354,6 @@ void ptdump_check_wx(void)
 	else
 		pr_info("Checked W+X mappings: passed, no W+X pages found\n");
 }
-#endif
 
 static int __init ptdump_init(void)
 {
diff --git a/arch/s390/mm/dump_pagetables.c b/arch/s390/mm/dump_pagetables.c
index 8dcb4e0c71bd..99da5a5602a8 100644
--- a/arch/s390/mm/dump_pagetables.c
+++ b/arch/s390/mm/dump_pagetables.c
@@ -121,7 +121,6 @@ static void print_prot(struct seq_file *m, unsigned int pr, int level)
 
 static void note_prot_wx(struct pg_state *st, unsigned long addr)
 {
-#ifdef CONFIG_DEBUG_WX
 	if (!st->check_wx)
 		return;
 	if (st->current_prot & _PAGE_INVALID)
@@ -138,10 +137,10 @@ static void note_prot_wx(struct pg_state *st, unsigned long addr)
 	 */
 	if (addr == PAGE_SIZE && (nospec_uses_trampoline() || !static_key_enabled(&cpu_has_bear)))
 		return;
-	WARN_ONCE(1, "s390/mm: Found insecure W+X mapping at address %pS\n",
+	WARN_ONCE(IS_ENABLED(CONFIG_DEBUG_WX),
+		  "s390/mm: Found insecure W+X mapping at address %pS\n",
 		  (void *)st->start_address);
 	st->wx_pages += (addr - st->start_address) / PAGE_SIZE;
-#endif /* CONFIG_DEBUG_WX */
 }
 
 static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level, u64 val)
@@ -193,7 +192,6 @@ static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
 	}
 }
 
-#ifdef CONFIG_DEBUG_WX
 void ptdump_check_wx(void)
 {
 	struct pg_state st = {
@@ -226,7 +224,6 @@ void ptdump_check_wx(void)
 			(nospec_uses_trampoline() || !static_key_enabled(&cpu_has_bear)) ?
 			"unexpected " : "");
 }
-#endif /* CONFIG_DEBUG_WX */
 
 #ifdef CONFIG_PTDUMP_DEBUGFS
 static int ptdump_show(struct seq_file *m, void *v)
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/4] ptdump: add check_wx_pages debugfs attribute
  2024-01-09 12:14 [PATCH 0/4] Refactor CONFIG_DEBUG_WX and check_wx_pages debugfs attribute Christophe Leroy
                   ` (2 preceding siblings ...)
  2024-01-09 12:14 ` [PATCH 3/4] powerpc,s390: Define ptdump_check_wx() regardless of CONFIG_DEBUG_WX Christophe Leroy
@ 2024-01-09 12:14 ` Christophe Leroy
  2024-01-09 13:50   ` Heiko Carstens
  3 siblings, 1 reply; 8+ messages in thread
From: Christophe Leroy @ 2024-01-09 12:14 UTC (permalink / raw)
  To: linux-hardening, Russell King, Catalin Marinas, Will Deacon,
	Michael Ellerman, Nicholas Piggin, Aneesh Kumar K.V,
	Naveen N. Rao, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Andrew Morton,
	Kees Cook
  Cc: Christophe Leroy, linux-arm-kernel, linux-kernel, linuxppc-dev,
	linux-riscv, linux-s390, linux-mm, steven.price, Phong Tran,
	mark.rutland, Greg KH

Add a writable attribute in debugfs to trigger a
W^X pages check at any time.

To trigger the test, just echo any numeric value into
/sys/kernel/debug/check_wx_pages

The result is provided into dmesg.

Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
---
 mm/ptdump.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/mm/ptdump.c b/mm/ptdump.c
index 03c1bdae4a43..e154099c2584 100644
--- a/mm/ptdump.c
+++ b/mm/ptdump.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 
 #include <linux/pagewalk.h>
+#include <linux/debugfs.h>
 #include <linux/ptdump.h>
 #include <linux/kasan.h>
 
@@ -163,3 +164,21 @@ void ptdump_walk_pgd(struct ptdump_state *st, struct mm_struct *mm, pgd_t *pgd)
 	/* Flush out the last page */
 	st->note_page(st, 0, -1, 0);
 }
+
+static int check_wx_debugfs_set(void *data, u64 val)
+{
+	ptdump_check_wx();
+
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(check_wx_fops, NULL, check_wx_debugfs_set, "%llu\n");
+
+static int ptdump_debugfs_init(void)
+{
+	debugfs_create_file("check_wx_pages", 0200, NULL, NULL, &check_wx_fops);
+
+	return 0;
+}
+
+device_initcall(ptdump_debugfs_init);
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH 2/4] arm64, powerpc, riscv, s390, x86: Refactor CONFIG_DEBUG_WX
  2024-01-09 12:14 ` [PATCH 2/4] arm64, powerpc, riscv, s390, x86: Refactor CONFIG_DEBUG_WX Christophe Leroy
@ 2024-01-09 12:54   ` Alexandre Ghiti
  0 siblings, 0 replies; 8+ messages in thread
From: Alexandre Ghiti @ 2024-01-09 12:54 UTC (permalink / raw)
  To: Christophe Leroy, linux-hardening, Russell King, Catalin Marinas,
	Will Deacon, Michael Ellerman, Nicholas Piggin, Aneesh Kumar K.V,
	Naveen N. Rao, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Andrew Morton,
	Kees Cook
  Cc: linux-arm-kernel, linux-kernel, linuxppc-dev, linux-riscv,
	linux-s390, linux-mm, steven.price, Phong Tran, mark.rutland,
	Greg KH

Hi Christophe,

On 09/01/2024 13:14, Christophe Leroy wrote:
> All architectures using the core ptdump functionality also implement
> CONFIG_DEBUG_WX, and they all do it more or less the same way, with a
> function called debug_checkwx() that is called by mark_rodata_ro(),
> which is a substitute to ptdump_check_wx() when CONFIG_DEBUG_WX is
> set and a no-op otherwise.
>
> Refactor by centraly defining debug_checkwx() in linux/ptdump.h and
> call debug_checkwx() immediately after calling mark_rodata_ro()
> instead of calling it at the end of every mark_rodata_ro().
>
> On x86_32, mark_rodata_ro() first checks __supported_pte_mask has
> _PAGE_NX before calling debug_checkwx(). Now the check is inside the
> callee ptdump_walk_pgd_level_checkwx().
>
> On powerpc_64, mark_rodata_ro() bails out early before calling
> ptdump_check_wx() when the MMU doesn't have KERNEL_RO feature. The
> check is now also done in ptdump_check_wx() as it is called outside
> mark_rodata_ro().
>
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> ---
>   arch/arm64/include/asm/ptdump.h |  7 -------
>   arch/arm64/mm/mmu.c             |  2 --
>   arch/powerpc/mm/mmu_decl.h      |  6 ------
>   arch/powerpc/mm/pgtable_32.c    |  4 ----
>   arch/powerpc/mm/pgtable_64.c    |  3 ---
>   arch/powerpc/mm/ptdump/ptdump.c |  3 +++
>   arch/riscv/include/asm/ptdump.h | 22 ----------------------
>   arch/riscv/mm/init.c            |  3 ---
>   arch/riscv/mm/ptdump.c          |  1 -
>   arch/s390/include/asm/ptdump.h  | 14 --------------
>   arch/s390/mm/dump_pagetables.c  |  1 -
>   arch/s390/mm/init.c             |  2 --
>   arch/x86/include/asm/pgtable.h  |  3 +--
>   arch/x86/mm/dump_pagetables.c   |  3 +++
>   arch/x86/mm/init_32.c           |  2 --
>   arch/x86/mm/init_64.c           |  2 --
>   include/linux/ptdump.h          |  7 +++++++
>   init/main.c                     |  2 ++
>   18 files changed, 16 insertions(+), 71 deletions(-)
>   delete mode 100644 arch/riscv/include/asm/ptdump.h
>   delete mode 100644 arch/s390/include/asm/ptdump.h
>
> diff --git a/arch/arm64/include/asm/ptdump.h b/arch/arm64/include/asm/ptdump.h
> index 581caac525b0..5b1701c76d1c 100644
> --- a/arch/arm64/include/asm/ptdump.h
> +++ b/arch/arm64/include/asm/ptdump.h
> @@ -29,13 +29,6 @@ void __init ptdump_debugfs_register(struct ptdump_info *info, const char *name);
>   static inline void ptdump_debugfs_register(struct ptdump_info *info,
>   					   const char *name) { }
>   #endif
> -void ptdump_check_wx(void);
>   #endif /* CONFIG_PTDUMP_CORE */
>   
> -#ifdef CONFIG_DEBUG_WX
> -#define debug_checkwx()	ptdump_check_wx()
> -#else
> -#define debug_checkwx()	do { } while (0)
> -#endif
> -
>   #endif /* __ASM_PTDUMP_H */
> diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c
> index 15f6347d23b6..e011beb2e5e3 100644
> --- a/arch/arm64/mm/mmu.c
> +++ b/arch/arm64/mm/mmu.c
> @@ -635,8 +635,6 @@ void mark_rodata_ro(void)
>   	section_size = (unsigned long)__init_begin - (unsigned long)__start_rodata;
>   	update_mapping_prot(__pa_symbol(__start_rodata), (unsigned long)__start_rodata,
>   			    section_size, PAGE_KERNEL_RO);
> -
> -	debug_checkwx();
>   }
>   
>   static void __init map_kernel_segment(pgd_t *pgdp, void *va_start, void *va_end,
> diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
> index 72341b9fb552..90dcc2844056 100644
> --- a/arch/powerpc/mm/mmu_decl.h
> +++ b/arch/powerpc/mm/mmu_decl.h
> @@ -171,12 +171,6 @@ static inline void mmu_mark_rodata_ro(void) { }
>   void __init mmu_mapin_immr(void);
>   #endif
>   
> -#ifdef CONFIG_DEBUG_WX
> -void ptdump_check_wx(void);
> -#else
> -static inline void ptdump_check_wx(void) { }
> -#endif
> -
>   static inline bool debug_pagealloc_enabled_or_kfence(void)
>   {
>   	return IS_ENABLED(CONFIG_KFENCE) || debug_pagealloc_enabled();
> diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
> index 5c02fd08d61e..12498017da8e 100644
> --- a/arch/powerpc/mm/pgtable_32.c
> +++ b/arch/powerpc/mm/pgtable_32.c
> @@ -153,7 +153,6 @@ void mark_rodata_ro(void)
>   
>   	if (v_block_mapped((unsigned long)_stext + 1)) {
>   		mmu_mark_rodata_ro();
> -		ptdump_check_wx();
>   		return;
>   	}
>   
> @@ -166,9 +165,6 @@ void mark_rodata_ro(void)
>   		   PFN_DOWN((unsigned long)_stext);
>   
>   	set_memory_ro((unsigned long)_stext, numpages);
> -
> -	// mark_initmem_nx() should have already run by now
> -	ptdump_check_wx();
>   }
>   #endif
>   
> diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
> index 5ac1fd30341b..1b366526f4f2 100644
> --- a/arch/powerpc/mm/pgtable_64.c
> +++ b/arch/powerpc/mm/pgtable_64.c
> @@ -150,9 +150,6 @@ void mark_rodata_ro(void)
>   		radix__mark_rodata_ro();
>   	else
>   		hash__mark_rodata_ro();
> -
> -	// mark_initmem_nx() should have already run by now
> -	ptdump_check_wx();
>   }
>   
>   void mark_initmem_nx(void)
> diff --git a/arch/powerpc/mm/ptdump/ptdump.c b/arch/powerpc/mm/ptdump/ptdump.c
> index 2313053fe679..620d4917ebe8 100644
> --- a/arch/powerpc/mm/ptdump/ptdump.c
> +++ b/arch/powerpc/mm/ptdump/ptdump.c
> @@ -343,6 +343,9 @@ void ptdump_check_wx(void)
>   		}
>   	};
>   
> +	if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && !mmu_has_feature(MMU_FTR_KERNEL_RO))
> +		return;
> +
>   	ptdump_walk_pgd(&st.ptdump, &init_mm, NULL);
>   
>   	if (st.wx_pages)
> diff --git a/arch/riscv/include/asm/ptdump.h b/arch/riscv/include/asm/ptdump.h
> deleted file mode 100644
> index 3c9ea6dd5af7..000000000000
> --- a/arch/riscv/include/asm/ptdump.h
> +++ /dev/null
> @@ -1,22 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -/*
> - * Copyright (C) 2019 SiFive
> - */
> -
> -#ifndef _ASM_RISCV_PTDUMP_H
> -#define _ASM_RISCV_PTDUMP_H
> -
> -void ptdump_check_wx(void);
> -
> -#ifdef CONFIG_DEBUG_WX
> -static inline void debug_checkwx(void)
> -{
> -	ptdump_check_wx();
> -}
> -#else
> -static inline void debug_checkwx(void)
> -{
> -}
> -#endif
> -
> -#endif /* _ASM_RISCV_PTDUMP_H */
> diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
> index 2e011cbddf3a..55c4deb1b332 100644
> --- a/arch/riscv/mm/init.c
> +++ b/arch/riscv/mm/init.c
> @@ -29,7 +29,6 @@
>   #include <asm/io.h>
>   #include <asm/numa.h>
>   #include <asm/pgtable.h>
> -#include <asm/ptdump.h>
>   #include <asm/sections.h>
>   #include <asm/soc.h>
>   #include <asm/tlbflush.h>
> @@ -720,8 +719,6 @@ void mark_rodata_ro(void)
>   	if (IS_ENABLED(CONFIG_64BIT))
>   		set_kernel_memory(lm_alias(__start_rodata), lm_alias(_data),
>   				  set_memory_ro);
> -
> -	debug_checkwx();
>   }
>   #else
>   static __init pgprot_t pgprot_from_va(uintptr_t va)
> diff --git a/arch/riscv/mm/ptdump.c b/arch/riscv/mm/ptdump.c
> index 657c27bc07a7..075265603313 100644
> --- a/arch/riscv/mm/ptdump.c
> +++ b/arch/riscv/mm/ptdump.c
> @@ -9,7 +9,6 @@
>   #include <linux/seq_file.h>
>   #include <linux/ptdump.h>
>   
> -#include <asm/ptdump.h>
>   #include <linux/pgtable.h>
>   #include <asm/kasan.h>
>   


For riscv, you can add:

Reviewed-by: Alexandre Ghiti <alexghiti@rivosinc.com>

Thanks,

Alex


> diff --git a/arch/s390/include/asm/ptdump.h b/arch/s390/include/asm/ptdump.h
> deleted file mode 100644
> index f960b2896606..000000000000
> --- a/arch/s390/include/asm/ptdump.h
> +++ /dev/null
> @@ -1,14 +0,0 @@
> -/* SPDX-License-Identifier: GPL-2.0 */
> -
> -#ifndef _ASM_S390_PTDUMP_H
> -#define _ASM_S390_PTDUMP_H
> -
> -void ptdump_check_wx(void);
> -
> -static inline void debug_checkwx(void)
> -{
> -	if (IS_ENABLED(CONFIG_DEBUG_WX))
> -		ptdump_check_wx();
> -}
> -
> -#endif /* _ASM_S390_PTDUMP_H */
> diff --git a/arch/s390/mm/dump_pagetables.c b/arch/s390/mm/dump_pagetables.c
> index d37a8f607b71..8dcb4e0c71bd 100644
> --- a/arch/s390/mm/dump_pagetables.c
> +++ b/arch/s390/mm/dump_pagetables.c
> @@ -6,7 +6,6 @@
>   #include <linux/mm.h>
>   #include <linux/kfence.h>
>   #include <linux/kasan.h>
> -#include <asm/ptdump.h>
>   #include <asm/kasan.h>
>   #include <asm/abs_lowcore.h>
>   #include <asm/nospec-branch.h>
> diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c
> index 43e612bc2bcd..d2e5eff9d1de 100644
> --- a/arch/s390/mm/init.c
> +++ b/arch/s390/mm/init.c
> @@ -37,7 +37,6 @@
>   #include <asm/pgalloc.h>
>   #include <asm/ctlreg.h>
>   #include <asm/kfence.h>
> -#include <asm/ptdump.h>
>   #include <asm/dma.h>
>   #include <asm/abs_lowcore.h>
>   #include <asm/tlb.h>
> @@ -109,7 +108,6 @@ void mark_rodata_ro(void)
>   
>   	__set_memory_ro(__start_ro_after_init, __end_ro_after_init);
>   	pr_info("Write protected read-only-after-init data: %luk\n", size >> 10);
> -	debug_checkwx();
>   }
>   
>   int set_memory_encrypted(unsigned long vaddr, int numpages)
> diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
> index 57bab91bbf50..036ce63f3b95 100644
> --- a/arch/x86/include/asm/pgtable.h
> +++ b/arch/x86/include/asm/pgtable.h
> @@ -32,6 +32,7 @@ void ptdump_walk_pgd_level(struct seq_file *m, struct mm_struct *mm);
>   void ptdump_walk_pgd_level_debugfs(struct seq_file *m, struct mm_struct *mm,
>   				   bool user);
>   void ptdump_walk_pgd_level_checkwx(void);
> +#define ptdump_check_wx() ptdump_walk_pgd_level_checkwx()
>   void ptdump_walk_user_pgd_level_checkwx(void);
>   
>   /*
> @@ -41,10 +42,8 @@ void ptdump_walk_user_pgd_level_checkwx(void);
>   #define pgprot_decrypted(prot)	__pgprot(cc_mkdec(pgprot_val(prot)))
>   
>   #ifdef CONFIG_DEBUG_WX
> -#define debug_checkwx()		ptdump_walk_pgd_level_checkwx()
>   #define debug_checkwx_user()	ptdump_walk_user_pgd_level_checkwx()
>   #else
> -#define debug_checkwx()		do { } while (0)
>   #define debug_checkwx_user()	do { } while (0)
>   #endif
>   
> diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
> index e1b599ecbbc2..0008524eebe9 100644
> --- a/arch/x86/mm/dump_pagetables.c
> +++ b/arch/x86/mm/dump_pagetables.c
> @@ -433,6 +433,9 @@ void ptdump_walk_user_pgd_level_checkwx(void)
>   
>   void ptdump_walk_pgd_level_checkwx(void)
>   {
> +	if (!(__supported_pte_mask & _PAGE_NX))
> +		return;
> +
>   	ptdump_walk_pgd_level_core(NULL, &init_mm, INIT_PGD, true, false);
>   }
>   
> diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
> index b63403d7179d..5c736b707cae 100644
> --- a/arch/x86/mm/init_32.c
> +++ b/arch/x86/mm/init_32.c
> @@ -800,6 +800,4 @@ void mark_rodata_ro(void)
>   	set_pages_ro(virt_to_page(start), size >> PAGE_SHIFT);
>   #endif
>   	mark_nxdata_nx();
> -	if (__supported_pte_mask & _PAGE_NX)
> -		debug_checkwx();
>   }
> diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
> index a190aae8ceaf..16e248769338 100644
> --- a/arch/x86/mm/init_64.c
> +++ b/arch/x86/mm/init_64.c
> @@ -1412,8 +1412,6 @@ void mark_rodata_ro(void)
>   				(void *)text_end, (void *)rodata_start);
>   	free_kernel_image_pages("unused kernel image (rodata/data gap)",
>   				(void *)rodata_end, (void *)_sdata);
> -
> -	debug_checkwx();
>   }
>   
>   /*
> diff --git a/include/linux/ptdump.h b/include/linux/ptdump.h
> index 2a3a95586425..c10513739bf9 100644
> --- a/include/linux/ptdump.h
> +++ b/include/linux/ptdump.h
> @@ -19,5 +19,12 @@ struct ptdump_state {
>   };
>   
>   void ptdump_walk_pgd(struct ptdump_state *st, struct mm_struct *mm, pgd_t *pgd);
> +void ptdump_check_wx(void);
> +
> +static inline void debug_checkwx(void)
> +{
> +	if (IS_ENABLED(CONFIG_DEBUG_WX))
> +		ptdump_check_wx();
> +}
>   
>   #endif /* _LINUX_PTDUMP_H */
> diff --git a/init/main.c b/init/main.c
> index e24b0780fdff..749a9f8d2c9b 100644
> --- a/init/main.c
> +++ b/init/main.c
> @@ -99,6 +99,7 @@
>   #include <linux/init_syscalls.h>
>   #include <linux/stackdepot.h>
>   #include <linux/randomize_kstack.h>
> +#include <linux/ptdump.h>
>   #include <net/net_namespace.h>
>   
>   #include <asm/io.h>
> @@ -1408,6 +1409,7 @@ static void mark_readonly(void)
>   		 */
>   		rcu_barrier();
>   		mark_rodata_ro();
> +		debug_checkwx();
>   		rodata_test();
>   	} else
>   		pr_info("Kernel memory protection disabled.\n");

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 4/4] ptdump: add check_wx_pages debugfs attribute
  2024-01-09 12:14 ` [PATCH 4/4] ptdump: add check_wx_pages debugfs attribute Christophe Leroy
@ 2024-01-09 13:50   ` Heiko Carstens
  0 siblings, 0 replies; 8+ messages in thread
From: Heiko Carstens @ 2024-01-09 13:50 UTC (permalink / raw)
  To: Christophe Leroy
  Cc: linux-hardening, Russell King, Catalin Marinas, Will Deacon,
	Michael Ellerman, Nicholas Piggin, Aneesh Kumar K.V,
	Naveen N. Rao, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Vasily Gorbik, Alexander Gordeev, Christian Borntraeger,
	Sven Schnelle, Gerald Schaefer, Thomas Gleixner, Ingo Molnar,
	Borislav Petkov, Dave Hansen, x86, H. Peter Anvin,
	Andy Lutomirski, Peter Zijlstra, Andrew Morton, Kees Cook,
	linux-arm-kernel, linux-kernel, linuxppc-dev, linux-riscv,
	linux-s390, linux-mm, steven.price, Phong Tran, mark.rutland,
	Greg KH

On Tue, Jan 09, 2024 at 01:14:38PM +0100, Christophe Leroy wrote:
> Add a writable attribute in debugfs to trigger a
> W^X pages check at any time.
> 
> To trigger the test, just echo any numeric value into
> /sys/kernel/debug/check_wx_pages
> 
> The result is provided into dmesg.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>
> ---
>  mm/ptdump.c | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
...
> +static int check_wx_debugfs_set(void *data, u64 val)
> +{
> +	ptdump_check_wx();
> +
> +	return 0;
> +}
> +
> +DEFINE_SIMPLE_ATTRIBUTE(check_wx_fops, NULL, check_wx_debugfs_set, "%llu\n");
> +
> +static int ptdump_debugfs_init(void)
> +{
> +	debugfs_create_file("check_wx_pages", 0200, NULL, NULL, &check_wx_fops);
> +
> +	return 0;
> +}

Wouldn't it be better to have (only?) a readable attribute which triggers
this, and provides the result via this attribute?
That would allow for automated tests without having to parse dmesg.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH 1/4] arm: ptdump: Rename CONFIG_DEBUG_WX to CONFIG_ARM_DEBUG_WX
  2024-01-09 12:14 ` [PATCH 1/4] arm: ptdump: Rename CONFIG_DEBUG_WX to CONFIG_ARM_DEBUG_WX Christophe Leroy
@ 2024-01-09 17:09   ` Florian Fainelli
  0 siblings, 0 replies; 8+ messages in thread
From: Florian Fainelli @ 2024-01-09 17:09 UTC (permalink / raw)
  To: Christophe Leroy, linux-hardening, Russell King, Catalin Marinas,
	Will Deacon, Michael Ellerman, Nicholas Piggin, Aneesh Kumar K.V,
	Naveen N. Rao, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
	Christian Borntraeger, Sven Schnelle, Gerald Schaefer,
	Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, x86,
	H. Peter Anvin, Andy Lutomirski, Peter Zijlstra, Andrew Morton,
	Kees Cook
  Cc: linux-arm-kernel, linux-kernel, linuxppc-dev, linux-riscv,
	linux-s390, linux-mm, steven.price, Phong Tran, mark.rutland,
	Greg KH

On 1/9/24 04:14, Christophe Leroy wrote:
> CONFIG_DEBUG_WX is a core option defined in mm/Kconfig.debug
> 
> To avoid any future conflict, rename ARM version
> into CONFIG_ARM_DEBUG_WX.
> 
> Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu>

Looks fine, you might also want to 
s/CONFIG_DEBUG_WX/CONFIG_ARM_DEBUG_WX/ in 
arch/arm/configs/aspeed_g{4,5}_defconfig so there are no surprises when 
people pull in those changes.
-- 
Florian


^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2024-01-09 17:09 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-09 12:14 [PATCH 0/4] Refactor CONFIG_DEBUG_WX and check_wx_pages debugfs attribute Christophe Leroy
2024-01-09 12:14 ` [PATCH 1/4] arm: ptdump: Rename CONFIG_DEBUG_WX to CONFIG_ARM_DEBUG_WX Christophe Leroy
2024-01-09 17:09   ` Florian Fainelli
2024-01-09 12:14 ` [PATCH 2/4] arm64, powerpc, riscv, s390, x86: Refactor CONFIG_DEBUG_WX Christophe Leroy
2024-01-09 12:54   ` Alexandre Ghiti
2024-01-09 12:14 ` [PATCH 3/4] powerpc,s390: Define ptdump_check_wx() regardless of CONFIG_DEBUG_WX Christophe Leroy
2024-01-09 12:14 ` [PATCH 4/4] ptdump: add check_wx_pages debugfs attribute Christophe Leroy
2024-01-09 13:50   ` Heiko Carstens

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).