* [PATCH] mm: snapshot alloc tags in alloc_tag_top_users() to avoid UAF
@ 2026-11-14 16:47 shao.mingyin
2026-11-14 17:31 ` Lorenzo Stoakes (ARM)
0 siblings, 1 reply; 2+ messages in thread
From: shao.mingyin @ 2026-11-14 16:47 UTC (permalink / raw)
To: surenb, akpm; +Cc: linux-mm, hao.ge, linux-kernel
From: Shao Mingyin <shao.mingyin@zte.com.cn>
mm: snapshot alloc tags in alloc_tag_top_users() to avoid UAF
alloc_tag_top_users() selects tags under the codetag module-list lock,
then returns raw codetag pointers. __show_mem() dereferences the tags,
their strings and per-CPU counters after that lock has been released.
Concurrent module unloading can invalidate those objects before they
are printed in the OOM or SysRq-m report.
Copy the selected tags and counters while holding the module-list lock,
and print only the copies. Reuse allocinfo_to_params(), which copies
names into fixed-size buffers and retains at most their last 63
characters. Preserve the signed comparison used to select the top tags.
Keep the larger output array static under the existing show_mem lock
to avoid increasing the stack frame. The counters remain approximate
lockless per-CPU observations; the copy protects object lifetime.
Fixes: 1438d349d16b ("lib: add memory allocations report in show_mem()")
Signed-off-by: Shao Mingyin <shao.mingyin@zte.com.cn>
---
Build-tested mm/alloc_tag.o and mm/show_mem.o with W=1 and
CONFIG_MEM_ALLOC_PROFILING=y on x86_64. The lock lifetime was reviewed
statically. No module-unload race was reproduced under KASAN.
include/linux/alloc_tag.h | 9 +++------
mm/alloc_tag.c | 17 ++++++++++-------
mm/show_mem.c | 29 +++++++++++++++++------------
3 files changed, 30 insertions(+), 25 deletions(-)
diff --git a/include/linux/alloc_tag.h b/include/linux/alloc_tag.h
index 9e42f23577b9638a8cad3ce42db7c7a2fb1a3d5a..018dbfc9db12e178c50ed0a67063db4e024bfccc 100644
--- a/include/linux/alloc_tag.h
+++ b/include/linux/alloc_tag.h
@@ -7,6 +7,7 @@
#include <linux/bug.h>
#include <linux/codetag.h>
+#include <uapi/linux/alloc_tag.h>
#include <linux/container_of.h>
#include <linux/preempt.h>
#include <asm/percpu.h>
@@ -76,12 +77,8 @@ static inline void set_codetag_empty(union codetag_ref *ref)
#define ALLOC_TAG_SECTION_NAME "alloc_tags"
-struct codetag_bytes {
- struct codetag *ct;
- s64 bytes;
-};
-
-size_t alloc_tag_top_users(struct codetag_bytes *tags, size_t count, bool can_sleep);
+size_t alloc_tag_top_users(struct allocinfo_tag_data *tags, size_t count,
+ bool can_sleep);
static inline struct alloc_tag *ct_to_alloc_tag(struct codetag *ct)
{
diff --git a/mm/alloc_tag.c b/mm/alloc_tag.c
index e9b70268eacb046f429107dc493cb5ade3620690..fe8269694c7dbc68a0c7188dcf87b3bbefbfb751 100644
--- a/mm/alloc_tag.c
+++ b/mm/alloc_tag.c
@@ -610,11 +610,11 @@ void alloc_tag_trace_mem_free(const void *ptr, struct alloc_tag *tag,
}
EXPORT_SYMBOL(alloc_tag_trace_mem_free);
-size_t alloc_tag_top_users(struct codetag_bytes *tags, size_t count, bool can_sleep)
+size_t alloc_tag_top_users(struct allocinfo_tag_data *tags, size_t count,
+ bool can_sleep)
{
struct codetag_iterator iter;
struct codetag *ct;
- struct codetag_bytes n;
unsigned int i, nr = 0;
if (IS_ERR_OR_NULL(alloc_tag_cttype))
@@ -629,11 +629,8 @@ size_t alloc_tag_top_users(struct codetag_bytes *tags, size_t count, bool can_sl
while ((ct = codetag_next_ct(&iter))) {
struct alloc_tag_counters counter = alloc_tag_read(ct_to_alloc_tag(ct));
- n.ct = ct;
- n.bytes = counter.bytes;
-
for (i = 0; i < nr; i++)
- if (n.bytes > tags[i].bytes)
+ if ((s64)counter.bytes > (s64)tags[i].counter.bytes)
break;
if (i < count) {
@@ -642,7 +639,13 @@ size_t alloc_tag_top_users(struct codetag_bytes *tags, size_t count, bool can_sl
&tags[i],
sizeof(tags[0]) * (nr - i));
nr++;
- tags[i] = n;
+ /*
+ * Snapshot the strings and counters while still
+ * holding the module list lock, so the caller does
+ * not dereference a module codetag that may have
+ * been unloaded by then.
+ */
+ allocinfo_to_params(ct, &tags[i], &counter);
}
}
diff --git a/mm/show_mem.c b/mm/show_mem.c
index b938cbcd774a1e2ec732f8c3703cae0dbe57d488..8d99a809f27fa9ca40a5184770ad0ec5b43f2aa1 100644
--- a/mm/show_mem.c
+++ b/mm/show_mem.c
@@ -436,7 +436,11 @@ void __show_mem(unsigned int filter, const nodemask_t *nodemask,
static DEFINE_SPINLOCK(mem_alloc_profiling_spinlock);
if (spin_trylock(&mem_alloc_profiling_spinlock)) {
- struct codetag_bytes tags[10];
+ /*
+ * Protected by mem_alloc_profiling_spinlock; kept static to
+ * avoid a large stack frame in this potentially atomic path.
+ */
+ static struct allocinfo_tag_data tags[10];
size_t i, nr;
nr = alloc_tag_top_users(tags, ARRAY_SIZE(tags), false);
@@ -444,22 +448,23 @@ void __show_mem(unsigned int filter, const nodemask_t *nodemask,
pr_notice("Memory allocations (profiling is currently turned %s):\n",
mem_alloc_profiling_enabled() ? "on" : "off");
for (i = 0; i < nr; i++) {
- struct codetag *ct = tags[i].ct;
- struct alloc_tag *tag = ct_to_alloc_tag(ct);
- struct alloc_tag_counters counter = alloc_tag_read(tag);
+ struct allocinfo_tag *tag = &tags[i].tag;
+ struct allocinfo_counter *counter = &tags[i].counter;
char bytes[10];
- string_get_size(counter.bytes, 1, STRING_UNITS_2, bytes, sizeof(bytes));
+ string_get_size(counter->bytes, 1,
+ STRING_UNITS_2, bytes,
+ sizeof(bytes));
/* Same as alloc_tag_to_text() but w/o intermediate buffer */
- if (ct->modname)
- pr_notice("%12s %8llu %s:%u [%s] func:%s\n",
- bytes, counter.calls, ct->filename,
- ct->lineno, ct->modname, ct->function);
+ if (tag->modname[0])
+ pr_notice("%12s %8llu %s:%llu [%s] func:%s\n",
+ bytes, counter->calls, tag->filename,
+ tag->lineno, tag->modname, tag->function);
else
- pr_notice("%12s %8llu %s:%u func:%s\n",
- bytes, counter.calls, ct->filename,
- ct->lineno, ct->function);
+ pr_notice("%12s %8llu %s:%llu func:%s\n",
+ bytes, counter->calls, tag->filename,
+ tag->lineno, tag->function);
}
}
spin_unlock(&mem_alloc_profiling_spinlock);
base-commit: 84abb955b1015477aa11a96e2f3ac1b938b77f48
--
2.43.0
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH] mm: snapshot alloc tags in alloc_tag_top_users() to avoid UAF
2026-11-14 16:47 [PATCH] mm: snapshot alloc tags in alloc_tag_top_users() to avoid UAF shao.mingyin
@ 2026-11-14 17:31 ` Lorenzo Stoakes (ARM)
0 siblings, 0 replies; 2+ messages in thread
From: Lorenzo Stoakes (ARM) @ 2026-11-14 17:31 UTC (permalink / raw)
To: shao.mingyin; +Cc: surenb, akpm, linux-mm, hao.ge, linux-kernel
On Sun, Nov 15, 2026 at 12:47:11AM +0800, shao.mingyin@zte.com.cn wrote:
> From: Shao Mingyin <shao.mingyin@zte.com.cn>
>
> mm: snapshot alloc tags in alloc_tag_top_users() to avoid UAF
>
> alloc_tag_top_users() selects tags under the codetag module-list lock,
> then returns raw codetag pointers. __show_mem() dereferences the tags,
> their strings and per-CPU counters after that lock has been released.
> Concurrent module unloading can invalidate those objects before they
> are printed in the OOM or SysRq-m report.
>
> Copy the selected tags and counters while holding the module-list lock,
> and print only the copies. Reuse allocinfo_to_params(), which copies
> names into fixed-size buffers and retains at most their last 63
> characters. Preserve the signed comparison used to select the top tags.
>
> Keep the larger output array static under the existing show_mem lock
> to avoid increasing the stack frame. The counters remain approximate
> lockless per-CPU observations; the copy protects object lifetime.
>
> Fixes: 1438d349d16b ("lib: add memory allocations report in show_mem()")
> Signed-off-by: Shao Mingyin <shao.mingyin@zte.com.cn>
NAK.
this is generated by some AI slopper's script, spamming the kernel. The
patches I looked at were wrong/broken, so no to anything from this person.
They've sent 300 mails in under four weeks spanniing: ata, scsi, target,
ufs, nvme/nvmet, ubifs, ublk, zloop, dm, md, mmc, virtio-blk, mfd, gpio,
pwm, spi, PCI, ASoC, ACPI, net, vfs mount, block partitions, and now mm.
and 17 series across 7 subsystems over the past 23 hours.
We need a way to ban emails from people like this...
--
Cheers, Lorenzo
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-11-14 17:31 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-14 16:47 [PATCH] mm: snapshot alloc tags in alloc_tag_top_users() to avoid UAF shao.mingyin
2026-11-14 17:31 ` Lorenzo Stoakes (ARM)
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.