FAILED: patch "[PATCH] mm: prevent droppable mappings from being locked" failed to apply to 6.12-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x d239462787b072c78eb19fc1f155c3d411256282
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026042736-vascular-rubbed-001c@gregkh' --subject-prefix 'PATCH 6.12.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From d239462787b072c78eb19fc1f155c3d411256282 Mon Sep 17 00:00:00 2001
From: Anthony Yznaga <[email protected]>
Date: Tue, 10 Mar 2026 08:58:20 -0700
Subject: [PATCH] mm: prevent droppable mappings from being locked
Droppable mappings must not be lockable. There is a check for VMAs with VM_DROPPABLE set in mlock_fixup() along with checks for other types of unlockable VMAs which ensures this when calling mlock()/mlock2().
For mlockall(MCL_FUTURE), the check for unlockable VMAs is different. In apply_mlockall_flags(), if the flags parameter has MCL_FUTURE set, the current task's mm's default VMA flag field mm->def_flags has VM_LOCKED applied to it. VM_LOCKONFAULT is also applied if MCL_ONFAULT is also set. When these flags are set as default in this manner they are cleared in __mmap_complete() for new mappings that do not support mlock. A check for VM_DROPPABLE in __mmap_complete() is missing resulting in droppable mappings created with VM_LOCKED set. To fix this and reduce that chance of similar bugs in the future, introduce and use vma_supports_mlock().
include/linux/hugetlb_inline.h +1 -1
@@ -30,7 +30,7 @@ static inline bool is_vma_hugetlb_flags(const vma_flags_t *flags)#endif -static inline bool is_vm_hugetlb_page (struct vm_area_struct *vma) +static inline bool is_vm_hugetlb_page (const struct vm_area_struct *vma) {return is_vm_hugetlb_flags (vma->vm_flags); }
mm/internal.h +10 -0
@@ -1243,6 +1243,16 @@ static inline struct file *maybe_unlock_mmap_for_io(struct vm_fault *vmf, }return fpin; } + +static inline bool vma_supports_mlock (const struct vm_area_struct *vma) +{ +if (vma->vm_flags & (VM_SPECIAL |VM_DROPPABLE )) +return false; +if (vma_is_dax (vma) ||is_vm_hugetlb_page (vma)) +return false; +return vma !=get_gate_vma (current->mm); +} +#else /* !CONFIG_MMU */ static inline void unmap_mapping_folio (struct folio *folio) { }static inline void mlock_new_folio (struct folio *folio) { }
mm/mlock.c +6 -4
@@ -472,10 +472,12 @@ static int mlock_fixup(struct vma_iterator *vmi, struct vm_area_struct *vma,int ret =0 ;vm_flags_t oldflags = vma->vm_flags; -if (newflags == oldflags || (oldflags &VM_SPECIAL ) || -is_vm_hugetlb_page (vma) || vma ==get_gate_vma (current->mm) || -vma_is_dax (vma) ||vma_is_secretmem (vma) || (oldflags &VM_DROPPABLE )) -/* don't set VM_LOCKED or VM_LOCKONFAULT and don't count */ +if (newflags == oldflags ||vma_is_secretmem (vma) || + !vma_supports_mlock (vma)) +/* +* Don't set VM_LOCKED or VM_LOCKONFAULT and don't count. +* For secretmem, don't allow the memory to be unlocked. +*/ goto out; vma =vma_modify_flags (vmi, *prev, vma, start, end, &newflags);
mm/vma.c +1 -3
@@ -2589,9 +2589,7 @@ static void __mmap_complete(struct mmap_state *map, struct vm_area_struct *vma)vm_stat_account (mm, vma->vm_flags, map->pglen);if (vm_flags &VM_LOCKED ) { -if ((vm_flags &VM_SPECIAL ) ||vma_is_dax (vma) || -is_vm_hugetlb_page (vma) || - vma ==get_gate_vma (mm)) +if (!vma_supports_mlock (vma))vm_flags_clear (vma,VM_LOCKED_MASK );else mm->locked_vm += map->pglen;
tools/testing/vma/include/stubs.h +5 -0
@@ -426,3 +426,8 @@ static inline void vma_adjust_trans_huge(struct vm_area_struct *vma, }static inline void hugetlb_split (struct vm_area_struct *,unsigned long ) {} + +static inline bool vma_supports_mlock (const struct vm_area_struct *vma) +{ +return false; +}
Sasha Levin
maintainerPATCH 1/1 mm: prevent droppable mappings from being locked
From: Anthony Yznaga <[email protected]>
[ Upstream commit d239462787b072c78eb19fc1f155c3d411256282 ]
Droppable mappings must not be lockable. There is a check for VMAs with VM_DROPPABLE set in mlock_fixup() along with checks for other types of unlockable VMAs which ensures this when calling mlock()/mlock2().
For mlockall(MCL_FUTURE), the check for unlockable VMAs is different. In apply_mlockall_flags(), if the flags parameter has MCL_FUTURE set, the current task's mm's default VMA flag field mm->def_flags has VM_LOCKED applied to it. VM_LOCKONFAULT is also applied if MCL_ONFAULT is also set. When these flags are set as default in this manner they are cleared in __mmap_complete() for new mappings that do not support mlock. A check for VM_DROPPABLE in __mmap_complete() is missing resulting in droppable mappings created with VM_LOCKED set. To fix this and reduce that chance of similar bugs in the future, introduce and use vma_supports_mlock().
--- include/linux/hugetlb_inline.h | 4 ++-- mm/internal.h | 10 ++++++++++ mm/mlock.c | 10 ++++++---- mm/mmap.c | 4 +--- 4 files changed, 19 insertions(+), 9 deletions(-)
include/linux/hugetlb_inline.h +2 -2
@@ -6,14 +6,14 @@#include <linux/mm.h> -static inline bool is_vm_hugetlb_page (struct vm_area_struct *vma) +static inline bool is_vm_hugetlb_page (const struct vm_area_struct *vma) {return !!(vma->vm_flags &VM_HUGETLB ); }#else -static inline bool is_vm_hugetlb_page (struct vm_area_struct *vma) +static inline bool is_vm_hugetlb_page (const struct vm_area_struct *vma) {return false; }
mm/internal.h +10 -0
@@ -1015,6 +1015,16 @@ static inline struct file *maybe_unlock_mmap_for_io(struct vm_fault *vmf, }return fpin; } + +static inline bool vma_supports_mlock (const struct vm_area_struct *vma) +{ +if (vma->vm_flags & (VM_SPECIAL |VM_DROPPABLE )) +return false; +if (vma_is_dax (vma) ||is_vm_hugetlb_page (vma)) +return false; +return vma !=get_gate_vma (current->mm); +} +#else /* !CONFIG_MMU */ static inline void unmap_mapping_folio (struct folio *folio) { }static inline void mlock_new_folio (struct folio *folio) { }
mm/mlock.c +6 -4
@@ -472,10 +472,12 @@ static int mlock_fixup(struct vma_iterator *vmi, struct vm_area_struct *vma,int ret =0 ;vm_flags_t oldflags = vma->vm_flags; -if (newflags == oldflags || (oldflags &VM_SPECIAL ) || -is_vm_hugetlb_page (vma) || vma ==get_gate_vma (current->mm) || -vma_is_dax (vma) ||vma_is_secretmem (vma) || (oldflags &VM_DROPPABLE )) -/* don't set VM_LOCKED or VM_LOCKONFAULT and don't count */ +if (newflags == oldflags ||vma_is_secretmem (vma) || + !vma_supports_mlock (vma)) +/* +* Don't set VM_LOCKED or VM_LOCKONFAULT and don't count. +* For secretmem, don't allow the memory to be unlocked. +*/ goto out; vma =vma_modify_flags (vmi, *prev, vma, start, end, newflags);
mm/mmap.c +1 -3
@@ -1547,9 +1547,7 @@ static unsigned long __mmap_region(struct file *file, unsigned long addr,vm_stat_account (mm, vm_flags, pglen);if (vm_flags &VM_LOCKED ) { -if ((vm_flags &VM_SPECIAL ) ||vma_is_dax (vma) || -is_vm_hugetlb_page (vma) || - vma ==get_gate_vma (current->mm)) +if (!vma_supports_mlock (vma))vm_flags_clear (vma,VM_LOCKED_MASK );else mm->locked_vm += pglen;
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 1/1 mm: prevent droppable mappings from being locked
In reply to [email protected]From: Anthony Yznaga <[email protected]>
[ Upstream commit d239462787b072c78eb19fc1f155c3d411256282 ]
Droppable mappings must not be lockable. There is a check for VMAs with VM_DROPPABLE set in mlock_fixup() along with checks for other types of unlockable VMAs which ensures this when calling mlock()/mlock2().
For mlockall(MCL_FUTURE), the check for unlockable VMAs is different. In apply_mlockall_flags(), if the flags parameter has MCL_FUTURE set, the current task's mm's default VMA flag field mm->def_flags has VM_LOCKED applied to it. VM_LOCKONFAULT is also applied if MCL_ONFAULT is also set. When these flags are set as default in this manner they are cleared in __mmap_complete() for new mappings that do not support mlock. A check for VM_DROPPABLE in __mmap_complete() is missing resulting in droppable mappings created with VM_LOCKED set. To fix this and reduce that chance of similar bugs in the future, introduce and use vma_supports_mlock().
--- include/linux/hugetlb_inline.h | 4 ++-- mm/internal.h | 10 ++++++++++ mm/mlock.c | 10 ++++++---- mm/mmap.c | 4 +--- 4 files changed, 19 insertions(+), 9 deletions(-)
include/linux/hugetlb_inline.h +2 -2
@@ -6,14 +6,14 @@#include <linux/mm.h> -static inline bool is_vm_hugetlb_page (struct vm_area_struct *vma) +static inline bool is_vm_hugetlb_page (const struct vm_area_struct *vma) {return !!(vma->vm_flags &VM_HUGETLB ); }#else -static inline bool is_vm_hugetlb_page (struct vm_area_struct *vma) +static inline bool is_vm_hugetlb_page (const struct vm_area_struct *vma) {return false; }
mm/internal.h +10 -0
@@ -1015,6 +1015,16 @@ static inline struct file *maybe_unlock_mmap_for_io(struct vm_fault *vmf, }return fpin; } + +static inline bool vma_supports_mlock (const struct vm_area_struct *vma) +{ +if (vma->vm_flags & (VM_SPECIAL |VM_DROPPABLE )) +return false; +if (vma_is_dax (vma) ||is_vm_hugetlb_page (vma)) +return false; +return vma !=get_gate_vma (current->mm); +} +#else /* !CONFIG_MMU */ static inline void unmap_mapping_folio (struct folio *folio) { }static inline void mlock_new_folio (struct folio *folio) { }
mm/mlock.c +6 -4
@@ -472,10 +472,12 @@ static int mlock_fixup(struct vma_iterator *vmi, struct vm_area_struct *vma,int ret =0 ;vm_flags_t oldflags = vma->vm_flags; -if (newflags == oldflags || (oldflags &VM_SPECIAL ) || -is_vm_hugetlb_page (vma) || vma ==get_gate_vma (current->mm) || -vma_is_dax (vma) ||vma_is_secretmem (vma) || (oldflags &VM_DROPPABLE )) -/* don't set VM_LOCKED or VM_LOCKONFAULT and don't count */ +if (newflags == oldflags ||vma_is_secretmem (vma) || + !vma_supports_mlock (vma)) +/* +* Don't set VM_LOCKED or VM_LOCKONFAULT and don't count. +* For secretmem, don't allow the memory to be unlocked. +*/ goto out; vma =vma_modify_flags (vmi, *prev, vma, start, end, newflags);
mm/mmap.c +1 -3
@@ -1547,9 +1547,7 @@ static unsigned long __mmap_region(struct file *file, unsigned long addr,vm_stat_account (mm, vm_flags, pglen);if (vm_flags &VM_LOCKED ) { -if ((vm_flags &VM_SPECIAL ) ||vma_is_dax (vma) || -is_vm_hugetlb_page (vma) || - vma ==get_gate_vma (current->mm)) +if (!vma_supports_mlock (vma))vm_flags_clear (vma,VM_LOCKED_MASK );else mm->locked_vm += pglen;
Signature · 1 line
2.53.0