Skip to content

Commit d5aad4c

Browse files
zevweissakpm00
authored andcommitted
prctl: generalize PR_SET_MDWE support check to be per-arch
Patch series "ARM: prctl: Reject PR_SET_MDWE where not supported". I noticed after a recent kernel update that my ARM926 system started segfaulting on any execve() after calling prctl(PR_SET_MDWE). After some investigation it appears that ARMv5 is incapable of providing the appropriate protections for MDWE, since any readable memory is also implicitly executable. The prctl_set_mdwe() function already had some special-case logic added disabling it on PARISC (commit 7938381, "prctl: Disable prctl(PR_SET_MDWE) on parisc"); this patch series (1) generalizes that check to use an arch_*() function, and (2) adds a corresponding override for ARM to disable MDWE on pre-ARMv6 CPUs. With the series applied, prctl(PR_SET_MDWE) is rejected on ARMv5 and subsequent execve() calls (as well as mmap(PROT_READ|PROT_WRITE)) can succeed instead of unconditionally failing; on ARMv6 the prctl works as it did previously. [0] https://lore.kernel.org/all/2023112456-linked-nape-bf19@gregkh/ This patch (of 2): There exist systems other than PARISC where MDWE may not be feasible to support; rather than cluttering up the generic code with additional arch-specific logic let's add a generic function for checking MDWE support and allow each arch to override it as needed. Link: https://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Zev Weiss <[email protected]> Acked-by: Helge Deller <[email protected]> [parisc] Cc: Borislav Petkov <[email protected]> Cc: David Hildenbrand <[email protected]> Cc: Florent Revest <[email protected]> Cc: "James E.J. Bottomley" <[email protected]> Cc: Josh Triplett <[email protected]> Cc: Kees Cook <[email protected]> Cc: Miguel Ojeda <[email protected]> Cc: Mike Rapoport (IBM) <[email protected]> Cc: Oleg Nesterov <[email protected]> Cc: Ondrej Mosnacek <[email protected]> Cc: Rick Edgecombe <[email protected]> Cc: Russell King (Oracle) <[email protected]> Cc: Sam James <[email protected]> Cc: Stefan Roesch <[email protected]> Cc: Yang Shi <[email protected]> Cc: Yin Fengwei <[email protected]> Cc: <[email protected]> [6.3+] Signed-off-by: Andrew Morton <[email protected]>
1 parent db09f2d commit d5aad4c

File tree

3 files changed

+27
-2
lines changed

3 files changed

+27
-2
lines changed

arch/parisc/include/asm/mman.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef __ASM_MMAN_H__
3+
#define __ASM_MMAN_H__
4+
5+
#include <uapi/asm/mman.h>
6+
7+
/* PARISC cannot allow mdwe as it needs writable stacks */
8+
static inline bool arch_memory_deny_write_exec_supported(void)
9+
{
10+
return false;
11+
}
12+
#define arch_memory_deny_write_exec_supported arch_memory_deny_write_exec_supported
13+
14+
#endif /* __ASM_MMAN_H__ */

include/linux/mman.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,14 @@ calc_vm_flag_bits(unsigned long flags)
162162

163163
unsigned long vm_commit_limit(void);
164164

165+
#ifndef arch_memory_deny_write_exec_supported
166+
static inline bool arch_memory_deny_write_exec_supported(void)
167+
{
168+
return true;
169+
}
170+
#define arch_memory_deny_write_exec_supported arch_memory_deny_write_exec_supported
171+
#endif
172+
165173
/*
166174
* Denies creating a writable executable mapping or gaining executable permissions.
167175
*

kernel/sys.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2408,8 +2408,11 @@ static inline int prctl_set_mdwe(unsigned long bits, unsigned long arg3,
24082408
if (bits & PR_MDWE_NO_INHERIT && !(bits & PR_MDWE_REFUSE_EXEC_GAIN))
24092409
return -EINVAL;
24102410

2411-
/* PARISC cannot allow mdwe as it needs writable stacks */
2412-
if (IS_ENABLED(CONFIG_PARISC))
2411+
/*
2412+
* EOPNOTSUPP might be more appropriate here in principle, but
2413+
* existing userspace depends on EINVAL specifically.
2414+
*/
2415+
if (!arch_memory_deny_write_exec_supported())
24132416
return -EINVAL;
24142417

24152418
current_bits = get_current_mdwe();

0 commit comments

Comments
 (0)