mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 20:54:03 +02:00
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.
Link: https://lore.kernel.org/20260714015117.78351-10-ye.liu@linux.dev
Fixes: fcf8935832 ("mm/page_owner: print memcg information")
Signed-off-by: Ye Liu <ye.liu@linux.dev>
Reported-by: Sashiko <sashiko-bot@kernel.org>
Reviewed-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Cc: Brendan Jackman <jackmanb@google.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: David Hildenbrand (Arm) <david@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
This commit is contained in:
parent
4fd1c85cc0
commit
90f095b816
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user