mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
mm: protect VMA modifications using VMA sequence count
The VMA sequence count has been introduced to allow fast detection of VMA modification when running a page fault handler without holding the mmap_sem. This patch provides protection against the VMA modification done in : - madvise() - mpol_rebind_policy() - vma_replace_policy() - change_prot_numa() - mlock(), munlock() - mprotect() - mmap_region() - collapse_huge_page() - userfaultd registering services In addition, VMA fields which will be read during the speculative fault path needs to be written using WRITE_ONCE to prevent write to be split and intermediate values to be pushed to other CPUs. Change-Id: Ic36046b7254e538b6baf7144c50ae577ee7f2074 Signed-off-by: Laurent Dufour <[email protected]> Patch-mainline: linux-mm @ Tue, 17 Apr 2018 16:33:15 [[email protected]: trivial merge conflict fixes] Signed-off-by: Vinayak Menon <[email protected]> [[email protected]: trivial merge conflict fixes] Signed-off-by: Charan Teja Reddy <[email protected]>
This commit is contained in:
parent
662540931e
commit
06219e6c87
9 changed files with 94 additions and 41 deletions
|
|
@ -675,8 +675,11 @@ int dup_userfaultfd(struct vm_area_struct *vma, struct list_head *fcs)
|
|||
|
||||
octx = vma->vm_userfaultfd_ctx.ctx;
|
||||
if (!octx || !(octx->features & UFFD_FEATURE_EVENT_FORK)) {
|
||||
vm_write_begin(vma);
|
||||
vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX;
|
||||
vma->vm_flags &= ~(VM_UFFD_WP | VM_UFFD_MISSING);
|
||||
WRITE_ONCE(vma->vm_flags,
|
||||
vma->vm_flags & ~(VM_UFFD_WP | VM_UFFD_MISSING));
|
||||
vm_write_end(vma);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -919,8 +922,10 @@ static int userfaultfd_release(struct inode *inode, struct file *file)
|
|||
else
|
||||
prev = vma;
|
||||
}
|
||||
vma->vm_flags = new_flags;
|
||||
vm_write_begin(vma);
|
||||
WRITE_ONCE(vma->vm_flags, new_flags);
|
||||
vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX;
|
||||
vm_write_end(vma);
|
||||
}
|
||||
up_write(&mm->mmap_sem);
|
||||
mmput(mm);
|
||||
|
|
@ -1487,8 +1492,10 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
|
|||
* the next vma was merged into the current one and
|
||||
* the current one has not been updated yet.
|
||||
*/
|
||||
vma->vm_flags = new_flags;
|
||||
vm_write_begin(vma);
|
||||
WRITE_ONCE(vma->vm_flags, new_flags);
|
||||
vma->vm_userfaultfd_ctx.ctx = ctx;
|
||||
vm_write_end(vma);
|
||||
|
||||
skip:
|
||||
prev = vma;
|
||||
|
|
@ -1650,8 +1657,10 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx,
|
|||
* the next vma was merged into the current one and
|
||||
* the current one has not been updated yet.
|
||||
*/
|
||||
vma->vm_flags = new_flags;
|
||||
vm_write_begin(vma);
|
||||
WRITE_ONCE(vma->vm_flags, new_flags);
|
||||
vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX;
|
||||
vm_write_end(vma);
|
||||
|
||||
skip:
|
||||
prev = vma;
|
||||
|
|
|
|||
Loading…
Reference in a new issue