The patch titled Subject: mm: add a NO_INHERIT flag to the PR_SET_MDWE prctl has been added to the -mm mm-unstable branch. Its filename is mm-add-a-no_inherit-flag-to-the-pr_set_mdwe-prctl.patch This patch will shortly appear at https://git.kernel.org/pub/scm/linux/kernel/git/akpm/25-new.git/tree/patches/mm-add-a-no_inherit-flag-to-the-pr_set_mdwe-prctl.patch This patch will later appear in the mm-unstable branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next via the mm-everything branch at git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm and is updated there every 2-3 working days ------------------------------------------------------ From: Florent Revest <revest@xxxxxxxxxxxx> Subject: mm: add a NO_INHERIT flag to the PR_SET_MDWE prctl Date: Mon, 28 Aug 2023 17:08:57 +0200 This extends the current PR_SET_MDWE prctl arg with a bit to indicate that the process doesn't want MDWE protection to propagate to children. To implement this no-inherit mode, the tag in current->mm->flags must be absent from MMF_INIT_MASK. This means that the encoding for "MDWE but without inherit" is different in the prctl than in the mm flags. This leads to a bit of bit-mangling in the prctl implementation. Link: https://lkml.kernel.org/r/20230828150858.393570-6-revest@xxxxxxxxxxxx Signed-off-by: Florent Revest <revest@xxxxxxxxxxxx> Reviewed-by: Kees Cook <keescook@xxxxxxxxxxxx> Reviewed-by: Catalin Marinas <catalin.marinas@xxxxxxx> Cc: Alexey Izbyshev <izbyshev@xxxxxxxxx> Cc: Anshuman Khandual <anshuman.khandual@xxxxxxx> Cc: Ayush Jain <ayush.jain3@xxxxxxx> Cc: David Hildenbrand <david@xxxxxxxxxx> Cc: Greg Thelen <gthelen@xxxxxxxxxx> Cc: Joey Gouly <joey.gouly@xxxxxxx> Cc: KP Singh <kpsingh@xxxxxxxxxx> Cc: Mark Brown <broonie@xxxxxxxxxx> Cc: Michal Hocko <mhocko@xxxxxxxx> Cc: Peter Xu <peterx@xxxxxxxxxx> Cc: Ryan Roberts <ryan.roberts@xxxxxxx> Cc: Szabolcs Nagy <Szabolcs.Nagy@xxxxxxx> Cc: Topi Miettinen <toiwoton@xxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- include/linux/sched/coredump.h | 10 +++++++++ include/uapi/linux/prctl.h | 1 kernel/fork.c | 2 - kernel/sys.c | 32 +++++++++++++++++++++++------ tools/include/uapi/linux/prctl.h | 1 5 files changed, 39 insertions(+), 7 deletions(-) --- a/include/linux/sched/coredump.h~mm-add-a-no_inherit-flag-to-the-pr_set_mdwe-prctl +++ a/include/linux/sched/coredump.h @@ -91,4 +91,14 @@ static inline int get_dumpable(struct mm MMF_DISABLE_THP_MASK | MMF_HAS_MDWE_MASK) #define MMF_VM_MERGE_ANY 29 +#define MMF_HAS_MDWE_NO_INHERIT 30 + +static inline unsigned long mmf_init_flags(unsigned long flags) +{ + if (flags & (1UL << MMF_HAS_MDWE_NO_INHERIT)) + flags &= ~((1UL << MMF_HAS_MDWE) | + (1UL << MMF_HAS_MDWE_NO_INHERIT)); + return flags & MMF_INIT_MASK; +} + #endif /* _LINUX_SCHED_COREDUMP_H */ --- a/include/uapi/linux/prctl.h~mm-add-a-no_inherit-flag-to-the-pr_set_mdwe-prctl +++ a/include/uapi/linux/prctl.h @@ -284,6 +284,7 @@ struct prctl_mm_map { /* Memory deny write / execute */ #define PR_SET_MDWE 65 # define PR_MDWE_REFUSE_EXEC_GAIN (1UL << 0) +# define PR_MDWE_NO_INHERIT (1UL << 1) #define PR_GET_MDWE 66 --- a/kernel/fork.c~mm-add-a-no_inherit-flag-to-the-pr_set_mdwe-prctl +++ a/kernel/fork.c @@ -1288,7 +1288,7 @@ static struct mm_struct *mm_init(struct hugetlb_count_init(mm); if (current->mm) { - mm->flags = current->mm->flags & MMF_INIT_MASK; + mm->flags = mmf_init_flags(current->mm->flags); mm->def_flags = current->mm->def_flags & VM_INIT_DEF_MASK; } else { mm->flags = default_dump_filter; --- a/kernel/sys.c~mm-add-a-no_inherit-flag-to-the-pr_set_mdwe-prctl +++ a/kernel/sys.c @@ -2368,19 +2368,41 @@ static int prctl_set_vma(unsigned long o } #endif /* CONFIG_ANON_VMA_NAME */ +static inline unsigned long get_current_mdwe(void) +{ + unsigned long ret = 0; + + if (test_bit(MMF_HAS_MDWE, ¤t->mm->flags)) + ret |= PR_MDWE_REFUSE_EXEC_GAIN; + if (test_bit(MMF_HAS_MDWE_NO_INHERIT, ¤t->mm->flags)) + ret |= PR_MDWE_NO_INHERIT; + + return ret; +} + static inline int prctl_set_mdwe(unsigned long bits, unsigned long arg3, unsigned long arg4, unsigned long arg5) { + unsigned long current_bits; + if (arg3 || arg4 || arg5) return -EINVAL; - if (bits & ~(PR_MDWE_REFUSE_EXEC_GAIN)) + if (bits & ~(PR_MDWE_REFUSE_EXEC_GAIN | PR_MDWE_NO_INHERIT)) + return -EINVAL; + + /* NO_INHERIT only makes sense with REFUSE_EXEC_GAIN */ + if (bits & PR_MDWE_NO_INHERIT && !(bits & PR_MDWE_REFUSE_EXEC_GAIN)) return -EINVAL; + current_bits = get_current_mdwe(); + if (current_bits && current_bits != bits) + return -EPERM; /* Cannot unset the flags */ + + if (bits & PR_MDWE_NO_INHERIT) + set_bit(MMF_HAS_MDWE_NO_INHERIT, ¤t->mm->flags); if (bits & PR_MDWE_REFUSE_EXEC_GAIN) set_bit(MMF_HAS_MDWE, ¤t->mm->flags); - else if (test_bit(MMF_HAS_MDWE, ¤t->mm->flags)) - return -EPERM; /* Cannot unset the flag */ return 0; } @@ -2390,9 +2412,7 @@ static inline int prctl_get_mdwe(unsigne { if (arg2 || arg3 || arg4 || arg5) return -EINVAL; - - return test_bit(MMF_HAS_MDWE, ¤t->mm->flags) ? - PR_MDWE_REFUSE_EXEC_GAIN : 0; + return get_current_mdwe(); } static int prctl_get_auxv(void __user *addr, unsigned long len) --- a/tools/include/uapi/linux/prctl.h~mm-add-a-no_inherit-flag-to-the-pr_set_mdwe-prctl +++ a/tools/include/uapi/linux/prctl.h @@ -284,6 +284,7 @@ struct prctl_mm_map { /* Memory deny write / execute */ #define PR_SET_MDWE 65 # define PR_MDWE_REFUSE_EXEC_GAIN (1UL << 0) +# define PR_MDWE_NO_INHERIT (1UL << 1) #define PR_GET_MDWE 66 _ Patches currently in -mm which might be from revest@xxxxxxxxxxxx are kselftest-vm-fix-tabs-spaces-inconsistency-in-the-mdwe-test.patch kselftest-vm-fix-mdwes-mmap_fixed-test-case.patch kselftest-vm-check-errnos-in-mdwe_test.patch mm-make-pr_mdwe_refuse_exec_gain-an-unsigned-long.patch mm-add-a-no_inherit-flag-to-the-pr_set_mdwe-prctl.patch kselftest-vm-add-tests-for-no-inherit-memory-deny-write-execute.patch