From: Jeff Xu <jeffxu@xxxxxxxxxx> mprotect(2) changes protection of VMAs in the given address range. Sealing will prevent unintended mprotect call. What this patch does: When a mprotect(2) is invoked, if one of its VMAs has MM_SEAL_MPROTECT set from previous mseal(2) call, this mprotect(2) will fail, without any VMA modified. This patch is based on following: 1. do_mprotect_pkey() currently called in two places: SYSCALL_DEFINE3(mprotect,...) SYSCALL_DEFINE4(pkey_mprotect, ...) and not in any other places, therefore omit changing the signature of do_mprotect_pkey(), i.e. not passing checkSeals flag. 2. In do_mprotect_pkey(), calls can_modify_mm() before any update is made on the VMAs. Signed-off-by: Jeff Xu <jeffxu@xxxxxxxxxx> --- mm/mprotect.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/mm/mprotect.c b/mm/mprotect.c index 130db91d3a8c..6321c4d0aa3f 100644 --- a/mm/mprotect.c +++ b/mm/mprotect.c @@ -32,6 +32,7 @@ #include <linux/sched/sysctl.h> #include <linux/userfaultfd_k.h> #include <linux/memory-tiers.h> +#include <uapi/linux/mman.h> #include <asm/cacheflush.h> #include <asm/mmu_context.h> #include <asm/tlbflush.h> @@ -753,6 +754,20 @@ static int do_mprotect_pkey(unsigned long start, size_t len, } } + /* + * do_mprotect_pkey() currently called from two places: + * SYSCALL_DEFINE3(mprotect,...) + * SYSCALL_DEFINE4(pkey_mprotect, ...) + * and not from other places. + * Therefore, omit changing the signature of do_mprotect_pkey(). + * Otherwise, we might need to add checkSeals and pass it + * from all callers of do_mprotect_pkey(). + */ + if (!can_modify_mm(current->mm, start, end, MM_SEAL_MPROTECT)) { + error = -EACCES; + goto out; + } + prev = vma_prev(&vmi); if (start > vma->vm_start) prev = vma; -- 2.42.0.655.g421f12c284-goog