mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
arch, mm: promote DEBUG_WX to CHECK_WX
Verification that the kernel does not have writable + executable mappings is about detecting security risks rather than a pure debug feature. Major distribution configurations enable it in their kernels as well as defconfigs of most architectures that have ARCH_HAS_DEBUG_WX. Rename relevant generic configuration options to use CHECK_WX and move their definitions from mm/Kconfig.debug to mm/Kconfig. Rename *debug_checkwx() funcitons and macros to *pgtable_checkwx(). For arm that does not widely enable it, only rename its variants of the config options. Enabling CHECK_WX adds a few kilobytes to the kernel binary and while the added size can be slightly reduced with churny updates of architecture implementations of ptdump, the core functionality takes most of the added size. It cannot be moved to .init.text because the verification has to happen after init sections are freed. With this, make generic CHECK_WX default to STRICT_KERNEL_RWX while still leaving users targeting small kernels the possibility to opt-out. Link: https://lore.kernel.org/20260926-direct-map-verify-wx-v2-1-efcd64a6b74a@kernel.org Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Suggested-by: Dave Hansen <dave.hansen@linux.intel.com> Acked-by: Lorenzo Stoakes (ARM) <ljs@kernel.org> Acked-by: Dave Hansen <dave.hansen@linux.intel.com> Acked-by: David Hildenbrand (Arm) <david@kernel.org> Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com> Cc: Albert Ou <aou@eecs.berkeley.edu> Cc: Alexander Gordeev <agordeev@linux.ibm.com> Cc: Alexandre Ghiti <alex@ghiti.fr> Cc: Borislav Petkov <bp@alien8.de> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Christophe Leroy <chleroy@kernel.org> Cc: Christian Borntraeger <borntraeger@linux.ibm.com> Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com> Cc: Heiko Carstens <hca@linux.ibm.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Liam R. Howlett <liam@infradead.org> Cc: Madhavan Srinivasan <maddy@linux.ibm.com> Cc: Mark Rutland <mark.rutland@arm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Michal Hocko <mhocko@suse.com> Cc: Nicholas Piggin <npiggin@gmail.com> Cc: Palmer Dabbelt <palmer@dabbelt.com> Cc: Paul Walmsley <pjw@kernel.org> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Ritesh Harjani (IBM) <ritesh.list@gmail.com> Cc: Russell King <linux@armlinux.org.uk> Cc: Shrikanth Hegde <sshegde@linux.ibm.com> Cc: Suren Baghdasaryan <surenb@google.com> Cc: Sven Schnelle <svens@linux.ibm.com> Cc: Thomas Gleixner <tglx@kernel.org> Cc: Vasily Gorbik <gor@linux.ibm.com> Cc: Vlastimil Babka <vbabka@kernel.org> Cc: Will Deacon <will@kernel.org>
This commit is contained in:
parent
d4113e9983
commit
2e83e2ce34
|
|
@ -17,7 +17,7 @@ config ARM_PTDUMP_DEBUGFS
|
|||
kernel.
|
||||
If in doubt, say "N"
|
||||
|
||||
config ARM_DEBUG_WX
|
||||
config ARM_CHECK_WX
|
||||
bool "Warn on W+X mappings at boot"
|
||||
depends on MMU
|
||||
select ARM_PTDUMP_CORE
|
||||
|
|
|
|||
|
|
@ -249,7 +249,7 @@ CONFIG_DEBUG_INFO_REDUCED=y
|
|||
CONFIG_GDB_SCRIPTS=y
|
||||
CONFIG_STRIP_ASM_SYMS=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_ARM_DEBUG_WX=y
|
||||
CONFIG_ARM_CHECK_WX=y
|
||||
CONFIG_SCHED_STACK_END_CHECK=y
|
||||
CONFIG_PANIC_ON_OOPS=y
|
||||
CONFIG_PANIC_TIMEOUT=-1
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ CONFIG_DEBUG_INFO_REDUCED=y
|
|||
CONFIG_GDB_SCRIPTS=y
|
||||
CONFIG_STRIP_ASM_SYMS=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_ARM_DEBUG_WX=y
|
||||
CONFIG_ARM_CHECK_WX=y
|
||||
CONFIG_SCHED_STACK_END_CHECK=y
|
||||
CONFIG_PANIC_ON_OOPS=y
|
||||
CONFIG_PANIC_TIMEOUT=-1
|
||||
|
|
|
|||
|
|
@ -225,4 +225,4 @@ CONFIG_CMA_SIZE_MBYTES=64
|
|||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_ARM_DEBUG_WX=y
|
||||
CONFIG_ARM_CHECK_WX=y
|
||||
|
|
|
|||
|
|
@ -32,10 +32,10 @@ void ptdump_check_wx(void);
|
|||
|
||||
#endif /* CONFIG_ARM_PTDUMP_CORE */
|
||||
|
||||
#ifdef CONFIG_ARM_DEBUG_WX
|
||||
#define arm_debug_checkwx() ptdump_check_wx()
|
||||
#ifdef CONFIG_ARM_CHECK_WX
|
||||
#define arm_pgtable_checkwx() ptdump_check_wx()
|
||||
#else
|
||||
#define arm_debug_checkwx() do { } while (0)
|
||||
#define arm_pgtable_checkwx() do { } while (0)
|
||||
#endif
|
||||
|
||||
#endif /* __ASM_PTDUMP_H */
|
||||
|
|
|
|||
|
|
@ -403,7 +403,7 @@ static int __mark_rodata_ro(void *unused)
|
|||
void mark_rodata_ro(void)
|
||||
{
|
||||
stop_machine(__mark_rodata_ro, NULL, NULL);
|
||||
arm_debug_checkwx();
|
||||
arm_pgtable_checkwx();
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ config ARM64
|
|||
select ACPI_MCFG if (ACPI && PCI)
|
||||
select ACPI_SPCR_TABLE if ACPI
|
||||
select ACPI_PPTT if ACPI
|
||||
select ARCH_HAS_DEBUG_WX
|
||||
select ARCH_HAS_CHECK_WX
|
||||
select ARCH_BINFMT_ELF_EXTRA_PHDRS
|
||||
select ARCH_BINFMT_ELF_STATE
|
||||
select ARCH_ENABLE_HUGEPAGE_MIGRATION if HUGETLB_PAGE && MIGRATION
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ config PPC
|
|||
select ARCH_HAS_CURRENT_STACK_POINTER
|
||||
select ARCH_HAS_DEBUG_VIRTUAL
|
||||
select ARCH_HAS_DEBUG_VM_PGTABLE
|
||||
select ARCH_HAS_DEBUG_WX if STRICT_KERNEL_RWX
|
||||
select ARCH_HAS_CHECK_WX if STRICT_KERNEL_RWX
|
||||
select ARCH_HAS_DEVMEM_IS_ALLOWED
|
||||
select ARCH_HAS_DMA_MAP_DIRECT if PPC_PSERIES
|
||||
select ARCH_HAS_DMA_OPS if PPC64
|
||||
|
|
|
|||
|
|
@ -393,7 +393,7 @@ CONFIG_MAGIC_SYSRQ=y
|
|||
CONFIG_PAGE_OWNER=y
|
||||
CONFIG_PAGE_POISONING=y
|
||||
CONFIG_DEBUG_RODATA_TEST=y
|
||||
CONFIG_DEBUG_WX=y
|
||||
CONFIG_CHECK_WX=y
|
||||
CONFIG_DEBUG_STACK_USAGE=y
|
||||
CONFIG_DEBUG_VM=y
|
||||
# CONFIG_DEBUG_VM_PGTABLE is not set
|
||||
|
|
|
|||
|
|
@ -191,7 +191,7 @@ static void note_prot_wx(struct pg_state *st, unsigned long addr)
|
|||
if (!pte_write(pte) || !pte_exec(pte))
|
||||
return;
|
||||
|
||||
WARN_ONCE(IS_ENABLED(CONFIG_DEBUG_WX),
|
||||
WARN_ONCE(IS_ENABLED(CONFIG_CHECK_WX),
|
||||
"powerpc/mm: Found insecure W+X mapping at address %p/%pS\n",
|
||||
(void *)st->start_address, (void *)st->start_address);
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ config RISCV
|
|||
select ARCH_HAS_CURRENT_STACK_POINTER
|
||||
select ARCH_HAS_DEBUG_VIRTUAL if MMU
|
||||
select ARCH_HAS_DEBUG_VM_PGTABLE
|
||||
select ARCH_HAS_DEBUG_WX
|
||||
select ARCH_HAS_CHECK_WX
|
||||
select ARCH_HAS_DELAY_TIMER
|
||||
select ARCH_HAS_ELF_CORE_EFLAGS if BINFMT_ELF && ELF_CORE
|
||||
select ARCH_HAS_FAST_MULTIPLIER
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ config S390
|
|||
select ARCH_HAS_CURRENT_STACK_POINTER
|
||||
select ARCH_HAS_DEBUG_VIRTUAL
|
||||
select ARCH_HAS_DEBUG_VM_PGTABLE
|
||||
select ARCH_HAS_DEBUG_WX
|
||||
select ARCH_HAS_CHECK_WX
|
||||
select ARCH_HAS_DEVMEM_IS_ALLOWED
|
||||
select ARCH_HAS_DMA_OPS if PCI
|
||||
select ARCH_HAS_ELF_RANDOMIZE
|
||||
|
|
|
|||
|
|
@ -841,7 +841,7 @@ CONFIG_DEBUG_PAGEALLOC=y
|
|||
CONFIG_SLUB_DEBUG_ON=y
|
||||
CONFIG_PAGE_OWNER=y
|
||||
CONFIG_DEBUG_RODATA_TEST=y
|
||||
CONFIG_DEBUG_WX=y
|
||||
CONFIG_CHECK_WX=y
|
||||
CONFIG_PTDUMP_DEBUGFS=y
|
||||
CONFIG_DEBUG_OBJECTS=y
|
||||
CONFIG_DEBUG_OBJECTS_SELFTEST=y
|
||||
|
|
|
|||
|
|
@ -820,7 +820,7 @@ CONFIG_DEBUG_INFO_DWARF4=y
|
|||
CONFIG_GDB_SCRIPTS=y
|
||||
CONFIG_DEBUG_SECTION_MISMATCH=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DEBUG_WX=y
|
||||
CONFIG_CHECK_WX=y
|
||||
CONFIG_PTDUMP_DEBUGFS=y
|
||||
CONFIG_DEBUG_MEMORY_INIT=y
|
||||
CONFIG_PANIC_ON_OOPS=y
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ static void note_prot_wx(struct pg_state *st, unsigned long addr)
|
|||
*/
|
||||
if (addr == PAGE_SIZE && (nospec_uses_trampoline() || !cpu_has_bear()))
|
||||
return;
|
||||
WARN_ONCE(IS_ENABLED(CONFIG_DEBUG_WX),
|
||||
WARN_ONCE(IS_ENABLED(CONFIG_CHECK_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;
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ config X86
|
|||
select ARCH_HAS_SYNC_CORE_BEFORE_USERMODE
|
||||
select ARCH_HAS_SYSCALL_WRAPPER
|
||||
select ARCH_HAS_UBSAN
|
||||
select ARCH_HAS_DEBUG_WX
|
||||
select ARCH_HAS_CHECK_WX
|
||||
select ARCH_HAS_ZONE_DMA_SET if EXPERT
|
||||
select ARCH_HAVE_NMI_SAFE_CMPXCHG
|
||||
select ARCH_HAVE_EXTRA_ELF_NOTES
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ CONFIG_SECURITY_SELINUX_BOOTPARAM=y
|
|||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DEBUG_WX=y
|
||||
CONFIG_CHECK_WX=y
|
||||
CONFIG_DEBUG_STACK_USAGE=y
|
||||
CONFIG_SCHEDSTATS=y
|
||||
CONFIG_BLK_DEV_IO_TRACE=y
|
||||
|
|
|
|||
|
|
@ -41,10 +41,10 @@ void ptdump_walk_user_pgd_level_checkwx(void);
|
|||
#define pgprot_encrypted(prot) __pgprot(cc_mkenc(pgprot_val(prot)))
|
||||
#define pgprot_decrypted(prot) __pgprot(cc_mkdec(pgprot_val(prot)))
|
||||
|
||||
#ifdef CONFIG_DEBUG_WX
|
||||
#define debug_checkwx_user() ptdump_walk_user_pgd_level_checkwx()
|
||||
#ifdef CONFIG_CHECK_WX
|
||||
#define pgtable_checkwx_user() ptdump_walk_user_pgd_level_checkwx()
|
||||
#else
|
||||
#define debug_checkwx_user() do { } while (0)
|
||||
#define pgtable_checkwx_user() do { } while (0)
|
||||
#endif
|
||||
|
||||
extern spinlock_t pgd_lock;
|
||||
|
|
|
|||
|
|
@ -688,5 +688,5 @@ void pti_finalize(void)
|
|||
pti_clone_entry_text(true);
|
||||
pti_clone_kernel_text();
|
||||
|
||||
debug_checkwx_user();
|
||||
pgtable_checkwx_user();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@ bool ptdump_walk_pgd_level_core(struct seq_file *m,
|
|||
void ptdump_walk_pgd(struct ptdump_state *st, struct mm_struct *mm, pgd_t *pgd);
|
||||
bool ptdump_check_wx(void);
|
||||
|
||||
static inline void debug_checkwx(void)
|
||||
static inline void pgtable_checkwx(void)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_DEBUG_WX))
|
||||
if (IS_ENABLED(CONFIG_CHECK_WX))
|
||||
ptdump_check_wx();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1535,7 +1535,7 @@ static void mark_readonly(void)
|
|||
flush_module_init_free_work();
|
||||
jump_label_init_ro();
|
||||
mark_rodata_ro();
|
||||
debug_checkwx();
|
||||
pgtable_checkwx();
|
||||
rodata_test();
|
||||
} else if (IS_ENABLED(CONFIG_STRICT_KERNEL_RWX)) {
|
||||
pr_info("Kernel memory protection disabled.\n");
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ CONFIG_DEBUG_NET=y
|
|||
# CONFIG_DEBUG_PAGEALLOC is not set
|
||||
# CONFIG_DEBUG_KMEMLEAK_DEFAULT_OFF is not set
|
||||
# CONFIG_DEBUG_RODATA_TEST is not set
|
||||
# CONFIG_DEBUG_WX is not set
|
||||
# CONFIG_CHECK_WX is not set
|
||||
# CONFIG_KFENCE is not set
|
||||
# CONFIG_PAGE_POISONING is not set
|
||||
# CONFIG_SLUB_STATS is not set
|
||||
|
|
|
|||
41
mm/Kconfig
41
mm/Kconfig
|
|
@ -1494,6 +1494,47 @@ config LAZY_MMU_MODE_KUNIT_TEST
|
|||
|
||||
If unsure, say N.
|
||||
|
||||
config ARCH_HAS_CHECK_WX
|
||||
bool
|
||||
|
||||
config CHECK_WX
|
||||
bool "Warn on W+X mappings at boot"
|
||||
default STRICT_KERNEL_RWX
|
||||
depends on ARCH_HAS_CHECK_WX
|
||||
depends on ARCH_HAS_PTDUMP
|
||||
depends on MMU
|
||||
select PTDUMP
|
||||
help
|
||||
Generate a warning if any W+X mappings are found at boot.
|
||||
|
||||
This is useful for discovering cases where the kernel is leaving W+X
|
||||
mappings after applying NX, as such mappings are a security risk.
|
||||
|
||||
Look for a message in dmesg output like this:
|
||||
|
||||
<arch>/mm: Checked W+X mappings: passed, no W+X pages found.
|
||||
|
||||
or like this, if the check failed:
|
||||
|
||||
<arch>/mm: Checked W+X mappings: failed, <N> W+X pages found.
|
||||
|
||||
Note that even if the check fails, your kernel is possibly
|
||||
still fine, as W+X mappings are not a security hole in
|
||||
themselves, what they do is that they make the exploitation
|
||||
of other unfixed kernel bugs easier.
|
||||
|
||||
There is no runtime or memory usage effect of this option
|
||||
once the kernel has booted up - it's a one time check.
|
||||
|
||||
If in doubt, say "Y".
|
||||
|
||||
config ARCH_HAS_PTDUMP
|
||||
bool
|
||||
|
||||
config PTDUMP
|
||||
bool
|
||||
|
||||
|
||||
source "mm/damon/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
|
|
|||
|
|
@ -180,45 +180,6 @@ config DEBUG_RODATA_TEST
|
|||
help
|
||||
This option enables a testcase for the setting rodata read-only.
|
||||
|
||||
config ARCH_HAS_DEBUG_WX
|
||||
bool
|
||||
|
||||
config DEBUG_WX
|
||||
bool "Warn on W+X mappings at boot"
|
||||
depends on ARCH_HAS_DEBUG_WX
|
||||
depends on ARCH_HAS_PTDUMP
|
||||
depends on MMU
|
||||
select PTDUMP
|
||||
help
|
||||
Generate a warning if any W+X mappings are found at boot.
|
||||
|
||||
This is useful for discovering cases where the kernel is leaving W+X
|
||||
mappings after applying NX, as such mappings are a security risk.
|
||||
|
||||
Look for a message in dmesg output like this:
|
||||
|
||||
<arch>/mm: Checked W+X mappings: passed, no W+X pages found.
|
||||
|
||||
or like this, if the check failed:
|
||||
|
||||
<arch>/mm: Checked W+X mappings: failed, <N> W+X pages found.
|
||||
|
||||
Note that even if the check fails, your kernel is possibly
|
||||
still fine, as W+X mappings are not a security hole in
|
||||
themselves, what they do is that they make the exploitation
|
||||
of other unfixed kernel bugs easier.
|
||||
|
||||
There is no runtime or memory usage effect of this option
|
||||
once the kernel has booted up - it's a one time check.
|
||||
|
||||
If in doubt, say "Y".
|
||||
|
||||
config ARCH_HAS_PTDUMP
|
||||
bool
|
||||
|
||||
config PTDUMP
|
||||
bool
|
||||
|
||||
config PTDUMP_DEBUGFS
|
||||
bool "Export kernel pagetable layout to userspace via debugfs"
|
||||
depends on DEBUG_KERNEL
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user