From: sashiko-bot@kernel.org
To: "Zhen Ni" <zhen.ni@easystack.cn>
Cc: bpf@vger.kernel.org
Subject: Re: [PATCH v2 5/6] mm/page_owner: add bpf_page_owner_get_memcg_info() kfunc
Date: Tue, 13 Oct 2026 12:49:00 +0000 [thread overview]
Message-ID: <sashiko-outbox-169738@kernel.org> (raw)
In-Reply-To: <20261013122125.843451-6-zhen.ni@easystack.cn>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] bpf: TOCTOU race in bpf_page_owner_get_memcg_info() leads to page fault
- [High] mm: wild pointer dereference in get_page_memcg_info() for tail pages
--
commit ab0ccc33a4ab8ccdaacb5f6b2dca8722bf6d6123
Author: Zhen Ni <zhen.ni@easystack.cn>
mm/page_owner: add bpf_page_owner_get_memcg_info() kfunc
This commit exposes per-page memcg information to BPF programs.
It splits memcg info collection out of print_page_owner_memcg() into
a new get_page_memcg_info() function and adds the
bpf_page_owner_get_memcg_info() kfunc.
Link: https://lore.kernel.org/linux-mm/20261009112308.240769-6-zhen.ni@easystack.cn/
> diff --git a/mm/page_owner.c b/mm/page_owner.c
> index 113e4e7e0b3a1..664121be66863 100644
> --- a/mm/page_owner.c
> +++ b/mm/page_owner.c
> @@ -538,16 +538,22 @@ void pagetypeinfo_showmixedcount_print(struct seq_file *m,
[ ... ]
> +int get_page_memcg_info(struct page *page, struct memcg_info *info,
> + char *buf, int size)
> {
> unsigned long memcg_data;
> struct obj_cgroup *objcg;
> struct mem_cgroup *memcg;
> + int ret = -ENODATA;
> +
> + *info = (struct memcg_info){};
>
> rcu_read_lock();
> memcg_data = READ_ONCE(page->memcg_data);
> + if (!memcg_data)
> + goto out_unlock;
[Severity: High]
Does removing the PageTail() guard here expose a wild pointer dereference?
In struct folio, the first tail page's _nr_pages field aliases exactly with
the memcg_data offset when CONFIG_MEMCG is enabled. Due to a lack of memory
barriers in __update_page_owner_handle(), page_owner_next_eligible() can
observe PAGE_EXT_OWNER_ALLOCATED before page_owner->order is updated,
yielding a tail page.
If a tail page is passed here, the non-zero _nr_pages value (e.g., 512 for a
large folio) will bypass the !memcg_data check and be dereferenced as an
obj_cgroup pointer later in the function, leading to a kernel panic.
[ ... ]
> diff --git a/mm/page_owner_iter.c b/mm/page_owner_iter.c
> index a2b90c8748520..86e0b4b52bfc7 100644
> --- a/mm/page_owner_iter.c
> +++ b/mm/page_owner_iter.c
> @@ -177,4 +177,21 @@ __bpf_kfunc int bpf_page_owner_stack_snprint(struct page_owner_scan *scan,
> 0);
> }
>
> +__bpf_kfunc int bpf_page_owner_get_memcg_info(struct page_owner_scan *scan,
> + struct memcg_info *info__uninit,
> + char *buf__uninit, u32 buf__sz)
> +{
> + /* Guard against the section being offlined after scan. */
> + struct page *page = pfn_to_online_page(scan->pfn);
> +
> + if (!page) {
> + *info__uninit = (struct memcg_info){};
> + if (buf__uninit && buf__sz)
> + buf__uninit[0] = '\0';
> + return -ENODATA;
> + }
> +
> + return get_page_memcg_info(page, info__uninit, buf__uninit, buf__sz);
> +}
[Severity: High]
Is this vulnerable to a time-of-check to time-of-use race with memory
hot-remove?
The pfn_to_online_page() check and subsequent get_page_memcg_info()
dereference occur without holding get_online_mems(). Because this is a
sleepable BPF kfunc (KF_SLEEPABLE), the thread can be preempted between the
check and the dereference.
If memory hot-remove offlines and removes the memory section concurrently, it
tears down the vmemmap backing the struct page. When the thread resumes and
get_page_memcg_info() attempts to read page->memcg_data, it will fault on the
unmapped address.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261013122125.843451-1-zhen.ni@easystack.cn?part=5
next prev parent reply other threads:[~2026-10-13 12:49 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-13 12:21 [PATCH v2 0/6] mm/page_owner: add bpf_iter and kfuncs Zhen Ni
2026-10-13 12:21 ` [PATCH v2 1/6] mm/page_owner: extract page_owner_next_eligible() from read loop Zhen Ni
2026-10-13 12:21 ` [PATCH v2 2/6] mm/page_owner: add bpf_iter target "page_owner" Zhen Ni
2026-10-13 13:51 ` bot+bpf-ci
2026-10-13 12:21 ` [PATCH v2 3/6] mm/page_owner: add open-coded page_owner iterator Zhen Ni
2026-10-13 12:49 ` sashiko-bot
2026-10-13 13:51 ` bot+bpf-ci
2026-10-13 12:21 ` [PATCH v2 4/6] mm/page_owner: record the NUMA node in the scan cursor Zhen Ni
2026-10-13 12:36 ` sashiko-bot
2026-10-13 12:21 ` [PATCH v2 5/6] mm/page_owner: add bpf_page_owner_get_memcg_info() kfunc Zhen Ni
2026-10-13 12:49 ` sashiko-bot [this message]
2026-10-13 12:21 ` [PATCH v2 6/6] selftests/bpf: add tests for the page_owner bpf_iter target Zhen Ni
2026-10-13 12:38 ` sashiko-bot
2026-10-13 17:17 ` [PATCH v2 0/6] mm/page_owner: add bpf_iter and kfuncs Zi Yan
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=sashiko-outbox-169738@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=bpf@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=zhen.ni@easystack.cn \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.