diff --git a/mm/mseal.c b/mm/mseal.c index 9781647483d1..430a252a6da4 100644 --- a/mm/mseal.c +++ b/mm/mseal.c @@ -16,32 +16,11 @@ #include #include "internal.h" -/* - * mseal() disallows an input range which contain unmapped ranges (VMA holes). - * - * It disallows unmapped regions from start to end whether they exist at the - * start, in the middle, or at the end of the range, or any combination thereof. - * - * This is because after sealing a range, there's nothing to stop memory mapping - * of ranges in the remaining gaps later, meaning that the user might then - * wrongly consider the entirety of the mseal()'d range to be sealed when it - * in fact isn't. - */ - -/* - * Does the [start, end) range contain any unmapped memory? - * - * We ensure that: - * - start is part of a valid VMA. - * - end is part of a valid VMA. - * - no gap (unallocated memory) exists between start and end. - */ -static bool range_contains_unmapped(struct mm_struct *mm, - unsigned long start, unsigned long end) +static bool range_contains_unmapped(unsigned long start, unsigned long end) { - struct vm_area_struct *vma; - unsigned long prev_end = start; VMA_ITERATOR(vmi, current->mm, start); + unsigned long prev_end = start; + struct vm_area_struct *vma; for_each_vma_range(vmi, vma, end) { if (vma->vm_start > prev_end) @@ -53,11 +32,10 @@ static bool range_contains_unmapped(struct mm_struct *mm, return prev_end < end; } -static int mseal_apply(struct mm_struct *mm, - unsigned long start, unsigned long end) +static int mseal_apply(unsigned long start, unsigned long end) { + VMA_ITERATOR(vmi, current->mm, start); struct vm_area_struct *vma, *prev; - VMA_ITERATOR(vmi, mm, start); /* We know there are no gaps so this will be non-NULL. */ vma = vma_iter_load(&vmi); @@ -142,10 +120,10 @@ static int mseal_apply(struct mm_struct *mm, */ int do_mseal(unsigned long start, size_t len_in, unsigned long flags) { - size_t len; - int ret = 0; - unsigned long end; struct mm_struct *mm = current->mm; + unsigned long end; + int ret = 0; + size_t len; /* Verify flags not set. */ if (flags) @@ -170,20 +148,11 @@ int do_mseal(unsigned long start, size_t len_in, unsigned long flags) if (mmap_write_lock_killable(mm)) return -EINTR; - if (range_contains_unmapped(mm, start, end)) { + if (range_contains_unmapped(start, end)) ret = -ENOMEM; - goto out; - } + else + ret = mseal_apply(start, end); - /* - * Second pass, this should success, unless there are errors - * from vma_modify_flags, e.g. merge/split error, or process - * reaching the max supported VMAs, however, those cases shall - * be rare. - */ - ret = mseal_apply(mm, start, end); - -out: mmap_write_unlock(mm); return ret; }