Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm/mseal: rework mseal apply logic

The logic can be simplified - firstly by renaming the inconsistently named
apply_mm_seal() to mseal_apply().

We then wrap mseal_fixup() into the main loop as the logic is simple
enough to not require it, equally it isn't a hugely pleasant pattern in
mprotect() etc. so it's not something we want to perpetuate.

We eliminate the need for invoking vma_iter_end() on each loop by directly
determining if the VMA was merged - the only thing we need concern
ourselves with is whether the start/end of the (gapless) range are offset
into VMAs.

This refactoring also avoids the rather horrid 'pass pointer to prev
around' pattern used in mprotect() et al.

No functional change intended.

Link: https://lkml.kernel.org/r/ddfa4376ce29f19a589d7dc8c92cb7d4f7605a4c.1753431105.git.lorenzo.stoakes@oracle.com
Signed-off-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Reviewed-by: Pedro Falcato <pfalcato@suse.de>
Reviewed-by: Liam R. Howlett <Liam.Howlett@oracle.com>
Acked-by: David Hildenbrand <david@redhat.com>
Acked-by: Jeff Xu <jeffxu@chromium.org>
Cc: Jann Horn <jannh@google.com>
Cc: Kees Cook <kees@kernel.org>
Cc: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Lorenzo Stoakes and committed by
Andrew Morton
6c2da14a 530e0909

+19 -46
+19 -46
mm/mseal.c
··· 15 15 #include <linux/sched.h> 16 16 #include "internal.h" 17 17 18 - static int mseal_fixup(struct vma_iterator *vmi, struct vm_area_struct *vma, 19 - struct vm_area_struct **prev, unsigned long start, 20 - unsigned long end, vm_flags_t newflags) 21 - { 22 - int ret = 0; 23 - vm_flags_t oldflags = vma->vm_flags; 24 - 25 - if (newflags == oldflags) 26 - goto out; 27 - 28 - vma = vma_modify_flags(vmi, *prev, vma, start, end, newflags); 29 - if (IS_ERR(vma)) { 30 - ret = PTR_ERR(vma); 31 - goto out; 32 - } 33 - 34 - vm_flags_set(vma, VM_SEALED); 35 - out: 36 - *prev = vma; 37 - return ret; 38 - } 39 - 40 18 /* 41 19 * mseal() disallows an input range which contain unmapped ranges (VMA holes). 42 20 * ··· 52 74 return prev_end < end; 53 75 } 54 76 55 - /* 56 - * Apply sealing. 57 - */ 58 - static int apply_mm_seal(unsigned long start, unsigned long end) 77 + static int mseal_apply(struct mm_struct *mm, 78 + unsigned long start, unsigned long end) 59 79 { 60 - unsigned long nstart; 61 80 struct vm_area_struct *vma, *prev; 62 - VMA_ITERATOR(vmi, current->mm, start); 81 + unsigned long curr_start = start; 82 + VMA_ITERATOR(vmi, mm, start); 63 83 84 + /* We know there are no gaps so this will be non-NULL. */ 64 85 vma = vma_iter_load(&vmi); 65 - /* 66 - * Note: check_mm_seal should already checked ENOMEM case. 67 - * so vma should not be null, same for the other ENOMEM cases. 68 - */ 69 86 prev = vma_prev(&vmi); 70 87 if (start > vma->vm_start) 71 88 prev = vma; 72 89 73 - nstart = start; 74 90 for_each_vma_range(vmi, vma, end) { 75 - int error; 76 - unsigned long tmp; 77 - vm_flags_t newflags; 91 + unsigned long curr_end = MIN(vma->vm_end, end); 78 92 79 - newflags = vma->vm_flags | VM_SEALED; 80 - tmp = vma->vm_end; 81 - if (tmp > end) 82 - tmp = end; 83 - error = mseal_fixup(&vmi, vma, &prev, nstart, tmp, newflags); 84 - if (error) 85 - return error; 86 - nstart = vma_iter_end(&vmi); 93 + if (!(vma->vm_flags & VM_SEALED)) { 94 + vma = vma_modify_flags(&vmi, prev, vma, 95 + curr_start, curr_end, 96 + vma->vm_flags | VM_SEALED); 97 + if (IS_ERR(vma)) 98 + return PTR_ERR(vma); 99 + vm_flags_set(vma, VM_SEALED); 100 + } 101 + 102 + prev = vma; 103 + curr_start = curr_end; 87 104 } 88 105 89 106 return 0; ··· 177 204 * reaching the max supported VMAs, however, those cases shall 178 205 * be rare. 179 206 */ 180 - ret = apply_mm_seal(start, end); 207 + ret = mseal_apply(mm, start, end); 181 208 182 209 out: 183 - mmap_write_unlock(current->mm); 210 + mmap_write_unlock(mm); 184 211 return ret; 185 212 } 186 213