From 66aebe42e60a00f8251262dac9c9db910a2c2257 Mon Sep 17 00:00:00 2001 From: Kalesh Singh Date: Mon, 23 Sep 2024 22:26:26 +0000 Subject: [PATCH] ANDROID: 16K: Fixup padding vm_flags bits on VMA splits In some cases VMAs are split without the mmap write lock held; later the lock is taken to fixup vm_flags of the original VMA. Since some uppper bits of vm_flags are used to encode the ELF padding ranges, they need to be modified on splits. This is usually handled correctly by __split_vma(). However in the above case, the flags get over witten later under the write lock. Preserve vm_flag bits on reset to correctly represent padding. Bug: 357901498 Change-Id: I1cb75419e614791a47cbdb0341373f619daf0bf2 Signed-off-by: Kalesh Singh --- fs/userfaultfd.c | 5 +++-- mm/madvise.c | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/fs/userfaultfd.c b/fs/userfaultfd.c index 8cc9faac4b9c..a572b13d086f 100644 --- a/fs/userfaultfd.c +++ b/fs/userfaultfd.c @@ -28,6 +28,7 @@ #include #include #include +#include int sysctl_unprivileged_userfaultfd __read_mostly; @@ -1511,7 +1512,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx, * the current one has not been updated yet. */ vm_write_begin(vma); - WRITE_ONCE(vma->vm_flags, new_flags); + WRITE_ONCE(vma->vm_flags, vma_pad_fixup_flags(vma, new_flags)); rcu_assign_pointer(vma->vm_userfaultfd_ctx.ctx, ctx); vm_write_end(vma); @@ -1694,7 +1695,7 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx, * the current one has not been updated yet. */ vm_write_begin(vma); - WRITE_ONCE(vma->vm_flags, new_flags); + WRITE_ONCE(vma->vm_flags, vma_pad_fixup_flags(vma, new_flags)); rcu_assign_pointer(vma->vm_userfaultfd_ctx.ctx, NULL); vm_write_end(vma); diff --git a/mm/madvise.c b/mm/madvise.c index 410f366b5df4..7d386e9051fb 100644 --- a/mm/madvise.c +++ b/mm/madvise.c @@ -172,7 +172,7 @@ static long madvise_behavior(struct vm_area_struct *vma, * vm_flags is protected by the mmap_lock held in write mode. */ vm_write_begin(vma); - WRITE_ONCE(vma->vm_flags, new_flags); + WRITE_ONCE(vma->vm_flags, vma_pad_fixup_flags(vma, new_flags)); vm_write_end(vma); out_convert_errno: