Files
android_kernel_fxtec_sm6115/include/linux
Jann Horn 6dbfc25d68 mm/rmap: Fix anon_vma->degree ambiguity leading to double-reuse
commit 2555283eb40df89945557273121e9393ef9b542b upstream.

anon_vma->degree tracks the combined number of child anon_vmas and VMAs
that use the anon_vma as their ->anon_vma.

anon_vma_clone() then assumes that for any anon_vma attached to
src->anon_vma_chain other than src->anon_vma, it is impossible for it to
be a leaf node of the VMA tree, meaning that for such VMAs ->degree is
elevated by 1 because of a child anon_vma, meaning that if ->degree
equals 1 there are no VMAs that use the anon_vma as their ->anon_vma.

This assumption is wrong because the ->degree optimization leads to leaf
nodes being abandoned on anon_vma_clone() - an existing anon_vma is
reused and no new parent-child relationship is created.  So it is
possible to reuse an anon_vma for one VMA while it is still tied to
another VMA.

This is an issue because is_mergeable_anon_vma() and its callers assume
that if two VMAs have the same ->anon_vma, the list of anon_vmas
attached to the VMAs is guaranteed to be the same.  When this assumption
is violated, vma_merge() can merge pages into a VMA that is not attached
to the corresponding anon_vma, leading to dangling page->mapping
pointers that will be dereferenced during rmap walks.

Fix it by separately tracking the number of child anon_vmas and the
number of VMAs using the anon_vma as their ->anon_vma.

Fixes: 7a3ef208e6 ("mm: prevent endless growth of anon_vma hierarchy")
Cc: stable@kernel.org
Acked-by: Michal Hocko <mhocko@suse.com>
Acked-by: Vlastimil Babka <vbabka@suse.cz>
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-09-05 10:26:34 +02:00
..
2019-12-13 08:51:18 +01:00
2019-10-05 13:10:03 +02:00
2019-11-24 08:19:14 +01:00
2021-12-08 08:50:13 +01:00
2021-12-08 08:50:13 +01:00
2021-01-30 13:32:12 +01:00
2019-10-17 13:45:42 -07:00
2021-05-22 10:59:50 +02:00
2019-12-13 08:52:43 +01:00
2021-03-04 09:39:44 +01:00
2022-08-25 11:15:23 +02:00
2021-02-07 14:48:38 +01:00
2021-11-26 11:35:57 +01:00
2019-12-31 16:35:38 +01:00
2021-07-11 12:49:26 +02:00
2020-07-29 10:16:52 +02:00
2021-06-30 08:48:18 -04:00
2021-09-03 09:58:00 +02:00
2020-03-18 07:14:17 +01:00
2021-12-14 10:18:04 +01:00
2020-04-02 15:28:22 +02:00
2020-12-11 13:25:01 +01:00
2020-04-02 15:28:23 +02:00
2021-12-14 10:18:06 +01:00