mirror of
https://github.com/nxp-imx/linux-imx.git
synced 2025-07-08 02:15:20 +02:00
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 <kaleshsingh@google.com>
This commit is contained in:
parent
7b43073a77
commit
4e714a2053
|
@ -27,6 +27,7 @@
|
||||||
#include <linux/sizes.h>
|
#include <linux/sizes.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
#include <linux/pgtable.h>
|
#include <linux/pgtable.h>
|
||||||
|
#include <linux/pgsize_migration_inline.h>
|
||||||
#include <linux/kasan.h>
|
#include <linux/kasan.h>
|
||||||
#include <linux/page_pinner.h>
|
#include <linux/page_pinner.h>
|
||||||
#include <linux/memremap.h>
|
#include <linux/memremap.h>
|
||||||
|
@ -844,6 +845,8 @@ static inline void vm_flags_reset(struct vm_area_struct *vma,
|
||||||
vm_flags_t flags)
|
vm_flags_t flags)
|
||||||
{
|
{
|
||||||
vma_assert_write_locked(vma);
|
vma_assert_write_locked(vma);
|
||||||
|
/* Preserve padding flags */
|
||||||
|
flags = vma_pad_fixup_flags(vma, flags);
|
||||||
vm_flags_init(vma, flags);
|
vm_flags_init(vma, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -851,6 +854,8 @@ static inline void vm_flags_reset_once(struct vm_area_struct *vma,
|
||||||
vm_flags_t flags)
|
vm_flags_t flags)
|
||||||
{
|
{
|
||||||
vma_assert_write_locked(vma);
|
vma_assert_write_locked(vma);
|
||||||
|
/* Preserve padding flags */
|
||||||
|
flags = vma_pad_fixup_flags(vma, flags);
|
||||||
WRITE_ONCE(ACCESS_PRIVATE(vma, __vm_flags), flags);
|
WRITE_ONCE(ACCESS_PRIVATE(vma, __vm_flags), flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -533,7 +533,7 @@ success:
|
||||||
if ((newflags & VM_LOCKED) && (oldflags & VM_LOCKED)) {
|
if ((newflags & VM_LOCKED) && (oldflags & VM_LOCKED)) {
|
||||||
/* No work to do, and mlocking twice would be wrong */
|
/* No work to do, and mlocking twice would be wrong */
|
||||||
vma_start_write(vma);
|
vma_start_write(vma);
|
||||||
vm_flags_reset(vma, vma_pad_fixup_flags(vma, newflags));
|
vm_flags_reset(vma, newflags);
|
||||||
} else {
|
} else {
|
||||||
mlock_vma_pages_range(vma, start, end, newflags);
|
mlock_vma_pages_range(vma, start, end, newflags);
|
||||||
}
|
}
|
||||||
|
|
|
@ -661,7 +661,7 @@ success:
|
||||||
* held in write mode.
|
* held in write mode.
|
||||||
*/
|
*/
|
||||||
vma_start_write(vma);
|
vma_start_write(vma);
|
||||||
vm_flags_reset(vma, vma_pad_fixup_flags(vma, newflags));
|
vm_flags_reset(vma, newflags);
|
||||||
if (vma_wants_manual_pte_write_upgrade(vma))
|
if (vma_wants_manual_pte_write_upgrade(vma))
|
||||||
mm_cp_flags |= MM_CP_TRY_CHANGE_WRITABLE;
|
mm_cp_flags |= MM_CP_TRY_CHANGE_WRITABLE;
|
||||||
vma_set_page_prot(vma);
|
vma_set_page_prot(vma);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user