Skip to content

Commit 942341d

Browse files
surenbaghdasaryantorvalds
authored andcommitted
mm: fix use-after-free when anon vma name is used after vma is freed
When adjacent vmas are being merged it can result in the vma that was originally passed to madvise_update_vma being destroyed. In the current implementation, the name parameter passed to madvise_update_vma points directly to vma->anon_name and it is used after the call to vma_merge. In the cases when vma_merge merges the original vma and destroys it, this might result in UAF. For that the original vma would have to hold the anon_vma_name with the last reference. The following vma would need to contain a different anon_vma_name object with the same string. Such scenario is shown below: madvise_vma_behavior(vma) madvise_update_vma(vma, ..., anon_name == vma->anon_name) vma_merge(vma) __vma_adjust(vma) <-- merges vma with adjacent one vm_area_free(vma) <-- frees the original vma replace_vma_anon_name(anon_name) <-- UAF of vma->anon_name Fix this by raising the name refcount and stabilizing it. Link: https://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected] Fixes: 9a10064 ("mm: add a field to store names for private anonymous memory") Signed-off-by: Suren Baghdasaryan <[email protected]> Reported-by: [email protected] Acked-by: Michal Hocko <[email protected]> Cc: Alexey Gladkov <[email protected]> Cc: Chris Hyser <[email protected]> Cc: Christian Brauner <[email protected]> Cc: Colin Cross <[email protected]> Cc: Cyrill Gorcunov <[email protected]> Cc: Dave Hansen <[email protected]> Cc: David Hildenbrand <[email protected]> Cc: Davidlohr Bueso <[email protected]> Cc: "Eric W. Biederman" <[email protected]> Cc: Johannes Weiner <[email protected]> Cc: Kees Cook <[email protected]> Cc: "Kirill A. Shutemov" <[email protected]> Cc: Matthew Wilcox <[email protected]> Cc: Michal Hocko <[email protected]> Cc: Peter Collingbourne <[email protected]> Cc: Sasha Levin <[email protected]> Cc: Sumit Semwal <[email protected]> Cc: Vlastimil Babka <[email protected]> Cc: Xiaofeng Cao <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 96403e1 commit 942341d

File tree

1 file changed

+7
-1
lines changed

1 file changed

+7
-1
lines changed

mm/madvise.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,8 @@ static int replace_anon_vma_name(struct vm_area_struct *vma,
131131
/*
132132
* Update the vm_flags on region of a vma, splitting it or merging it as
133133
* necessary. Must be called with mmap_sem held for writing;
134+
* Caller should ensure anon_name stability by raising its refcount even when
135+
* anon_name belongs to a valid vma because this function might free that vma.
134136
*/
135137
static int madvise_update_vma(struct vm_area_struct *vma,
136138
struct vm_area_struct **prev, unsigned long start,
@@ -945,6 +947,7 @@ static int madvise_vma_behavior(struct vm_area_struct *vma,
945947
unsigned long behavior)
946948
{
947949
int error;
950+
struct anon_vma_name *anon_name;
948951
unsigned long new_flags = vma->vm_flags;
949952

950953
switch (behavior) {
@@ -1010,8 +1013,11 @@ static int madvise_vma_behavior(struct vm_area_struct *vma,
10101013
break;
10111014
}
10121015

1016+
anon_name = anon_vma_name(vma);
1017+
anon_vma_name_get(anon_name);
10131018
error = madvise_update_vma(vma, prev, start, end, new_flags,
1014-
anon_vma_name(vma));
1019+
anon_name);
1020+
anon_vma_name_put(anon_name);
10151021

10161022
out:
10171023
/*

0 commit comments

Comments
 (0)