From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
stable@vger.kernel.org, stable@kernel.org,
Michal Hocko <mhocko@suse.com>, Vlastimil Babka <vbabka@suse.cz>,
Jann Horn <jannh@google.com>,
Linus Torvalds <torvalds@linux-foundation.org>
Subject: [PATCH 5.15 35/73] mm/rmap: Fix anon_vma->degree ambiguity leading to double-reuse
Date: Fri, 2 Sep 2022 14:18:59 +0200 [thread overview]
Message-ID: <20220902121405.599778788@linuxfoundation.org> (raw)
In-Reply-To: <20220902121404.435662285@linuxfoundation.org>
From: Jann Horn <jannh@google.com>
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: 7a3ef208e662 ("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>
---
include/linux/rmap.h | 7 +++++--
mm/rmap.c | 29 ++++++++++++++++-------------
2 files changed, 21 insertions(+), 15 deletions(-)
--- a/include/linux/rmap.h
+++ b/include/linux/rmap.h
@@ -39,12 +39,15 @@ struct anon_vma {
atomic_t refcount;
/*
- * Count of child anon_vmas and VMAs which points to this anon_vma.
+ * Count of child anon_vmas. Equals to the count of all anon_vmas that
+ * have ->parent pointing to this one, including itself.
*
* This counter is used for making decision about reusing anon_vma
* instead of forking new one. See comments in function anon_vma_clone.
*/
- unsigned degree;
+ unsigned long num_children;
+ /* Count of VMAs whose ->anon_vma pointer points to this object. */
+ unsigned long num_active_vmas;
struct anon_vma *parent; /* Parent of this anon_vma */
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -90,7 +90,8 @@ static inline struct anon_vma *anon_vma_
anon_vma = kmem_cache_alloc(anon_vma_cachep, GFP_KERNEL);
if (anon_vma) {
atomic_set(&anon_vma->refcount, 1);
- anon_vma->degree = 1; /* Reference for first vma */
+ anon_vma->num_children = 0;
+ anon_vma->num_active_vmas = 0;
anon_vma->parent = anon_vma;
/*
* Initialise the anon_vma root to point to itself. If called
@@ -198,6 +199,7 @@ int __anon_vma_prepare(struct vm_area_st
anon_vma = anon_vma_alloc();
if (unlikely(!anon_vma))
goto out_enomem_free_avc;
+ anon_vma->num_children++; /* self-parent link for new root */
allocated = anon_vma;
}
@@ -207,8 +209,7 @@ int __anon_vma_prepare(struct vm_area_st
if (likely(!vma->anon_vma)) {
vma->anon_vma = anon_vma;
anon_vma_chain_link(vma, avc, anon_vma);
- /* vma reference or self-parent link for new root */
- anon_vma->degree++;
+ anon_vma->num_active_vmas++;
allocated = NULL;
avc = NULL;
}
@@ -293,19 +294,19 @@ int anon_vma_clone(struct vm_area_struct
anon_vma_chain_link(dst, avc, anon_vma);
/*
- * Reuse existing anon_vma if its degree lower than two,
- * that means it has no vma and only one anon_vma child.
+ * Reuse existing anon_vma if it has no vma and only one
+ * anon_vma child.
*
- * Do not chose parent anon_vma, otherwise first child
- * will always reuse it. Root anon_vma is never reused:
+ * Root anon_vma is never reused:
* it has self-parent reference and at least one child.
*/
if (!dst->anon_vma && src->anon_vma &&
- anon_vma != src->anon_vma && anon_vma->degree < 2)
+ anon_vma->num_children < 2 &&
+ anon_vma->num_active_vmas == 0)
dst->anon_vma = anon_vma;
}
if (dst->anon_vma)
- dst->anon_vma->degree++;
+ dst->anon_vma->num_active_vmas++;
unlock_anon_vma_root(root);
return 0;
@@ -355,6 +356,7 @@ int anon_vma_fork(struct vm_area_struct
anon_vma = anon_vma_alloc();
if (!anon_vma)
goto out_error;
+ anon_vma->num_active_vmas++;
avc = anon_vma_chain_alloc(GFP_KERNEL);
if (!avc)
goto out_error_free_anon_vma;
@@ -375,7 +377,7 @@ int anon_vma_fork(struct vm_area_struct
vma->anon_vma = anon_vma;
anon_vma_lock_write(anon_vma);
anon_vma_chain_link(vma, avc, anon_vma);
- anon_vma->parent->degree++;
+ anon_vma->parent->num_children++;
anon_vma_unlock_write(anon_vma);
return 0;
@@ -407,7 +409,7 @@ void unlink_anon_vmas(struct vm_area_str
* to free them outside the lock.
*/
if (RB_EMPTY_ROOT(&anon_vma->rb_root.rb_root)) {
- anon_vma->parent->degree--;
+ anon_vma->parent->num_children--;
continue;
}
@@ -415,7 +417,7 @@ void unlink_anon_vmas(struct vm_area_str
anon_vma_chain_free(avc);
}
if (vma->anon_vma) {
- vma->anon_vma->degree--;
+ vma->anon_vma->num_active_vmas--;
/*
* vma would still be needed after unlink, and anon_vma will be prepared
@@ -433,7 +435,8 @@ void unlink_anon_vmas(struct vm_area_str
list_for_each_entry_safe(avc, next, &vma->anon_vma_chain, same_vma) {
struct anon_vma *anon_vma = avc->anon_vma;
- VM_WARN_ON(anon_vma->degree);
+ VM_WARN_ON(anon_vma->num_children);
+ VM_WARN_ON(anon_vma->num_active_vmas);
put_anon_vma(anon_vma);
list_del(&avc->same_vma);
next prev parent reply other threads:[~2022-09-02 12:44 UTC|newest]
Thread overview: 82+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-09-02 12:18 [PATCH 5.15 00/73] 5.15.65-rc1 review Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 01/73] mm: Force TLB flush for PFNMAP mappings before unlink_file_vma() Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 02/73] drm/bridge: Add stubs for devm_drm_of_get_bridge when OF is disabled Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 03/73] ACPI: thermal: drop an always true check Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 04/73] drm/vc4: hdmi: Rework power up Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 05/73] drm/vc4: hdmi: Depends on CONFIG_PM Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 06/73] firmware: tegra: bpmp: Do only aligned access to IPC memory area Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 07/73] crypto: lib - remove unneeded selection of XOR_BLOCKS Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 08/73] Drivers: hv: balloon: Support status report for larger page sizes Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 09/73] mm/hugetlb: avoid corrupting page->mapping in hugetlb_mcopy_atomic_pte Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 10/73] arm64: errata: Add Cortex-A510 to the repeat tlbi list Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 11/73] io_uring: correct fill events helpers types Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 12/73] io_uring: clean cqe filling functions Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 13/73] io_uring: refactor poll update Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 14/73] io_uring: move common poll bits Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 15/73] io_uring: kill poll linking optimisation Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 16/73] io_uring: inline io_poll_complete Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 17/73] io_uring: poll rework Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 18/73] io_uring: Remove unused function req_ref_put Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 19/73] io_uring: remove poll entry from list when canceling all Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 20/73] io_uring: bump poll refs to full 31-bits Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 21/73] io_uring: fail links when poll fails Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 22/73] io_uring: fix wrong arm_poll error handling Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 23/73] io_uring: fix UAF due to missing POLLFREE handling Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 24/73] kbuild: Fix include path in scripts/Makefile.modpost Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 25/73] Bluetooth: L2CAP: Fix build errors in some archs Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 26/73] Revert "PCI/portdrv: Dont disable AER reporting in get_port_device_capability()" Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 27/73] HID: steam: Prevent NULL pointer dereference in steam_{recv,send}_report Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 28/73] udmabuf: Set the DMA mask for the udmabuf device (v2) Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 29/73] media: pvrusb2: fix memory leak in pvr_probe Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 30/73] HID: hidraw: fix memory leak in hidraw_release() Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 31/73] net: fix refcount bug in sk_psock_get (2) Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 32/73] fbdev: fb_pm2fb: Avoid potential divide by zero error Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 33/73] ftrace: Fix NULL pointer dereference in is_ftrace_trampoline when ftrace is dead Greg Kroah-Hartman
2022-09-02 12:18 ` [PATCH 5.15 34/73] bpf: Dont redirect packets with invalid pkt_len Greg Kroah-Hartman
2022-09-02 12:18 ` Greg Kroah-Hartman [this message]
2022-09-02 12:19 ` [PATCH 5.15 36/73] ALSA: usb-audio: Add quirk for LH Labs Geek Out HD Audio 1V5 Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 37/73] HID: add Lenovo Yoga C630 battery quirk Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 38/73] HID: AMD_SFH: Add a DMI quirk entry for Chromebooks Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 39/73] HID: asus: ROG NKey: Ignore portion of 0x5a report Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 40/73] HID: thrustmaster: Add sparco wheel and fix array length Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 41/73] drm/i915/gt: Skip TLB invalidations once wedged Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 42/73] mmc: mtk-sd: Clear interrupts when cqe off/disable Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 43/73] mmc: sdhci-of-dwcmshc: add reset call back for rockchip Socs Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 44/73] mmc: sdhci-of-dwcmshc: rename rk3568 to rk35xx Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 45/73] mmc: sdhci-of-dwcmshc: Re-enable support for the BlueField-3 SoC Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 46/73] btrfs: remove root argument from btrfs_unlink_inode() Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 47/73] btrfs: remove no longer needed logic for replaying directory deletes Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 48/73] btrfs: add and use helper for unlinking inode during log replay Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 49/73] btrfs: fix warning during log replay when bumping inode link count Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 50/73] fs/ntfs3: Fix work with fragmented xattr Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 51/73] ASoC: sh: rz-ssi: Improve error handling in rz_ssi_probe() error path Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 52/73] drm/amd/display: Avoid MPC infinite loop Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 53/73] drm/amd/display: Fix HDMI VSIF V3 incorrect issue Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 54/73] drm/amd/display: For stereo keep "FLIP_ANY_FRAME" Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 55/73] drm/amd/display: clear optc underflow before turn off odm clock Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 56/73] ksmbd: return STATUS_BAD_NETWORK_NAME error status if share is not configured Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 57/73] neigh: fix possible DoS due to net iface start/stop loop Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 58/73] s390/hypfs: avoid error message under KVM Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 59/73] ksmbd: dont remove dos attribute xattr on O_TRUNC open Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 60/73] drm/amd/pm: add missing ->fini_microcode interface for Sienna Cichlid Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 61/73] drm/amd/display: Fix pixel clock programming Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 62/73] drm/amdgpu: Increase tlb flush timeout for sriov Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 63/73] drm/amd/display: avoid doing vm_init multiple time Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 64/73] netfilter: conntrack: NF_CONNTRACK_PROCFS should no longer default to y Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 65/73] testing: selftests: nft_flowtable.sh: use random netns names Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 66/73] btrfs: move lockdep class helpers to locking.c Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 67/73] btrfs: fix lockdep splat with reloc root extent buffers Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 68/73] btrfs: tree-checker: check for overlapping extent items Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 69/73] kprobes: dont call disarm_kprobe() for disabled kprobes Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 70/73] btrfs: fix space cache corruption and potential double allocations Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 71/73] android: binder: fix lockdep check on clearing vma Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 72/73] net/af_packet: check len when min_header_len equals to 0 Greg Kroah-Hartman
2022-09-02 12:19 ` [PATCH 5.15 73/73] net: neigh: dont call kfree_skb() under spin_lock_irqsave() Greg Kroah-Hartman
2022-09-02 16:36 ` [PATCH 5.15 00/73] 5.15.65-rc1 review Jon Hunter
2022-09-02 18:00 ` Florian Fainelli
2022-09-02 22:06 ` Shuah Khan
2022-09-03 0:36 ` Guenter Roeck
2022-09-03 3:33 ` Naresh Kamboju
2022-09-03 4:10 ` Bagas Sanjaya
2022-09-03 7:42 ` Ron Economos
2022-09-03 10:47 ` Sudip Mukherjee
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220902121405.599778788@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=jannh@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mhocko@suse.com \
--cc=stable@kernel.org \
--cc=stable@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
--cc=vbabka@suse.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox