FAILED: patch "[PATCH] mm/page_owner: use memcg_data snapshot to avoid TOCTOU in" failed to apply to 6.1-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 6.1-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.1.y
git checkout FETCH_HEAD
git cherry-pick -x 90f095b816e25c6a9e4446d299bac5007fdcb3df
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026090314-dagger-sharpness-8cd1@gregkh' --subject-prefix 'PATCH 6.1.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 90f095b816e25c6a9e4446d299bac5007fdcb3df Mon Sep 17 00:00:00 2001
From: Ye Liu <[email protected]>
Date: Tue, 14 Jul 2026 09:51:08 +0800
Subject: [PATCH] mm/page_owner: use memcg_data snapshot to avoid TOCTOU in
print_page_owner_memcg()
print_page_owner_memcg() reads page->memcg_data via READ_ONCE() at the start to guard against tail pages and NULL data. However, it later re-reads page->memcg_data locklessly in two places:
1: page_memcg_check(page)
2: PageMemcgKmem(page) (via folio_memcg_kmem(), which includes
VM_BUG_ON assertions for tail pages and MEMCG_DATA_OBJEXTS)
If the page is concurrently freed and reallocated as a THP tail page or slab page between these calls, the VM_BUG_ON assertions can trigger on CONFIG_DEBUG_VM=y builds, crashing the kernel.
Fix both TOCTOU issues by using the memcg_data snapshot throughout.
mm/page_owner.c +7 -3
@@ -540,6 +540,7 @@ static inline int print_page_owner_memcg(char *kbuf, size_t count, int ret, struct page *page) {unsigned long memcg_data; +struct obj_cgroup *objcg;struct mem_cgroup *memcg;bool online;char name[80 ];
@@ -549,11 +550,14 @@ static inline int print_page_owner_memcg(char *kbuf, size_t count, int ret,if (!memcg_data ||PageTail (page)) goto out_unlock; -if (memcg_data &MEMCG_DATA_OBJEXTS ) +if (memcg_data &MEMCG_DATA_OBJEXTS ) { ret +=scnprintf (kbuf + ret, count - ret,"Slab cache page\n" ); + goto out_unlock; + } - memcg =page_memcg_check (page); + objcg = (void *)(memcg_data & ~OBJEXTS_FLAGS_MASK ); + memcg = objcg ?obj_cgroup_memcg (objcg) :NULL ;if (!memcg) goto out_unlock;
@@ -561,7 +565,7 @@ static inline int print_page_owner_memcg(char *kbuf, size_t count, int ret,cgroup_name (memcg->css.cgroup, name,sizeof (name)); ret +=scnprintf (kbuf + ret, count - ret,"Charged %sto %smemcg %s\n" , -PageMemcgKmem (page) ?"(via objcg) " :"" , + (memcg_data &MEMCG_DATA_KMEM ) ?"(via objcg) " :"" , online ?"" :"offline " , name); out_unlock:
Sasha Levin
maintainerPATCH 1/1 mm/page_owner: use memcg_data snapshot to avoid TOCTOU in print_page_owner_memcg()
From: Ye Liu <[email protected]>
[ Upstream commit 90f095b816e25c6a9e4446d299bac5007fdcb3df ]
print_page_owner_memcg() reads page->memcg_data via READ_ONCE() at the start to guard against tail pages and NULL data. However, it later re-reads page->memcg_data locklessly in two places:
1: page_memcg_check(page)
2: PageMemcgKmem(page) (via folio_memcg_kmem(), which includes
VM_BUG_ON assertions for tail pages and MEMCG_DATA_OBJEXTS)
If the page is concurrently freed and reallocated as a THP tail page or slab page between these calls, the VM_BUG_ON assertions can trigger on CONFIG_DEBUG_VM=y builds, crashing the kernel.
Fix both TOCTOU issues by using the memcg_data snapshot throughout.
--- mm/page_owner.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
mm/page_owner.c +12 -4
@@ -361,20 +361,28 @@ static inline int print_page_owner_memcg(char *kbuf, size_t count, int ret, {#ifdef CONFIG_MEMCG unsigned long memcg_data; +struct obj_cgroup *objcg;struct mem_cgroup *memcg;bool online;char name[80 ];rcu_read_lock (); memcg_data =READ_ONCE (page->memcg_data); -if (!memcg_data) +if (!memcg_data ||PageTail (page)) goto out_unlock; -if (memcg_data &MEMCG_DATA_OBJCGS ) +if (memcg_data &MEMCG_DATA_OBJCGS ) { ret +=scnprintf (kbuf + ret, count - ret,"Slab cache page\n" ); + goto out_unlock; + } - memcg =page_memcg_check (page); +if (memcg_data &MEMCG_DATA_KMEM ) { + objcg = (void *)(memcg_data & ~MEMCG_DATA_FLAGS_MASK ); + memcg = objcg ?obj_cgroup_memcg (objcg) :NULL ; + }else { + memcg = (void *)(memcg_data & ~MEMCG_DATA_FLAGS_MASK ); + }if (!memcg) goto out_unlock;
@@ -382,7 +390,7 @@ static inline int print_page_owner_memcg(char *kbuf, size_t count, int ret,cgroup_name (memcg->css.cgroup, name,sizeof (name)); ret +=scnprintf (kbuf + ret, count - ret,"Charged %sto %smemcg %s\n" , -PageMemcgKmem (page) ?"(via objcg) " :"" , + (memcg_data &MEMCG_DATA_KMEM ) ?"(via objcg) " :"" , online ?"" :"offline " , name); out_unlock:
Signature · 1 line
2.53.0