From: Hao Ge <hao.ge@linux.dev>
To: Sashiko <sashiko-bot@kernel.org>
Cc: linux-modules@vger.kernel.org,
Suren Baghdasaryan <surenb@google.com>,
Andrew Morton <akpm@linux-foundation.org>,
Petr Pavlu <petr.pavlu@suse.com>
Subject: Re: [PATCH v7 3/4] module: allocate codetag sections before the regular module layout
Date: Thu, 3 Sep 2026 14:17:58 +0800 [thread overview]
Message-ID: <920be24a-f8be-4388-b1bc-6bad0cfbb178@linux.dev> (raw)
In-Reply-To: <20260902083652.2C3BD1F00A3D@smtp.kernel.org>
On 2026/9/2 16:36, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
>
> New issues:
> - [High] Per-CPU memory leak of module allocation tag counters on module unload when falling back to regular section allocation.
> - [Medium] Skipping memcpy for SHT_NOBITS codetag sections leaves them filled with uninitialized kernel memory.
>
> Pre-existing issues:
> - [High] AB-BA deadlock between `/proc/allocinfo` file readers (`pde->in_use`) and module loading (`cttype->mod_lock`).
> --
>
> commit 073ca6b0680c884f9d863cdcbd7d5db665a17c3b
> Author: Hao Ge <hao.ge@linux.dev>
>
> module: allocate codetag sections before the regular module layout
>
> Whether a codetag section goes to the codetag region is decided by
> layout_sections() and asked again in move_module(). A concurrent
> load can shut profiling down in between, and move_module() then
> copies the section to offset 0 of its regular destination,
> overwriting whatever is there.
>
> Link: https://lore.kernel.org/all/499bb60c-c6e3-43a3-bd92-95a0567ece5e@suse.com/
>
>> diff --git a/kernel/module/main.c b/kernel/module/main.c
>> index b114b815187a9..b94830c5b9a10 100644
>> --- a/kernel/module/main.c
>> +++ b/kernel/module/main.c
>
> [ ... ]
>
>> @@ -2940,6 +2901,47 @@ static bool blacklisted(const char *module_name)
>> }
>> core_param(module_blacklist, module_blacklist, charp, 0400);
>>
>> +/*
>> + * Allocate codetag sections separately. They are loaded into preallocated
>> + * contiguous memory because they may still be used after the module is
>> + * unloaded.
>> + *
>> + * If the separate allocation overflows, allocate the section normally
>> + * so that the module can still be loaded.
>> + */
>> +static int allocate_codetag_sections(struct load_info *info)
>> +{
>> + for (unsigned int i = 1; i < info->hdr->e_shnum; i++) {
>> + Elf_Shdr *shdr = &info->sechdrs[i];
>> + const char *sname = info->secstrings + shdr->sh_name;
>> + void *dest;
>> +
>> + if (!codetag_needs_module_section(info->mod, sname, shdr->sh_size))
>> + continue;
>> +
>> + dest = codetag_alloc_module_section(info->mod, sname, shdr->sh_size,
>> + arch_mod_section_prepend(info->mod, i), shdr->sh_addralign);
>> + if (WARN_ON(!dest)) {
>> + codetag_free_module_sections(info->mod);
>> + return -EINVAL;
>> + }
>> + if (dest == ERR_PTR(-EAGAIN))
>> + /* Allocate the section as a regular section. */
>> + continue;
>
> [Severity: High]
> Does this code leak the per-cpu memory on module unload when falling back to
> regular section allocation?
>
> If tags_addressable() returns false, reserve_module_tags() returns -EAGAIN
> and removes the module from mod_area_mt. The fallback mechanism here allocates
> the tags in regular module memory, but the module loading process still
> unconditionally allocates per-cpu counters for each tag, oblivious to the
> fallback or the disabled profiling state:
>
> for (tag = start_tag; tag < stop_tag; tag++) {
> WARN_ON(tag->counters);
> tag->counters = alloc_percpu(struct alloc_tag_counters);
>
> On unload, release_module_tags() fails to find the module in mod_area_mt
> because it was removed, skipping clean_unused_counters() and leaking the
> previously allocated per-cpu memory.
This has already been fixed by the commit below:
https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git/commit/?id=394aff7091a0278b0495549b5d2ff3b318e639d2
>
>> + if (IS_ERR(dest)) {
>> + codetag_free_module_sections(info->mod);
>> + return PTR_ERR(dest);
>> + }
>> +
>> + if (shdr->sh_type != SHT_NOBITS)
>> + memcpy(dest, (void *)shdr->sh_addr, shdr->sh_size);
>
> [Severity: Medium]
> Could this expose uninitialized kernel memory if the codetag section is
> parsed from an ELF module with the SHT_NOBITS type?
>
> The code skips memcpy() but fails to use memset() to zero-initialize the
> destination buffer. Regular module sections are safe because
> module_memory_alloc() explicitly zeroes them, but reserve_module_tags() backs
> its memory with alloc_pages_bulk_node() without the __GFP_ZERO flag:
>
OK. Considering that codetag is a general‑purpose framework,
it shouldn't assume anything about which codetag types exist
today or later. Will fix for the next version.
> mm/alloc_tag.c:vm_module_tags_populate() {
> ...
> allocated = alloc_pages_bulk_node(GFP_KERNEL | __GFP_NOWARN,
> NUMA_NO_NODE, more_pages - nr, next_page + nr);
> ...
> }
>
>> + shdr->sh_addr = (unsigned long)dest;
>> + shdr->sh_entsize = SH_ENTSIZE_STANDALONE;
>> + }
>> +
>> + return 0;
>> +}
>> +
>
> [ ... ]
>
>> diff --git a/mm/alloc_tag.c b/mm/alloc_tag.c
>> index 2070e682fe106..112a014d4b890 100644
>> --- a/mm/alloc_tag.c
>> +++ b/mm/alloc_tag.c
>> @@ -950,10 +950,12 @@ static void *reserve_module_tags(struct module *mod, unsigned long size,
>> int grow_res;
>>
>> module_tags.size = offset + size;
>> - if (mem_alloc_profiling_enabled() && !tags_addressable()) {
>> + if (!tags_addressable()) {
>> shutdown_mem_profiling(true);
>
> [Severity: High]
> This is a pre-existing issue, but does this shutdown_mem_profiling(true) call
> introduce an AB-BA deadlock between /proc/allocinfo file readers (pde->in_use)
> and module loading (cttype->mod_lock)?
>
> A user reading /proc/allocinfo acquires the procfs in_use reference in
> use_pde(), then blocks on down_read(&alloc_tag_cttype->mod_lock) in
> allocinfo_start().
>
> Concurrently, if a module loads and tags_addressable() fails,
> codetag_alloc_module_section() holds down_write(&cttype->mod_lock) and calls
> shutdown_mem_profiling(true), which removes the proc entry. This removal waits
> indefinitely for the in_use reference to drop to zero, hanging both procfs
> reads and module loading.
>
>> - pr_warn("With module %s there are too many tags to fit in %d page flag bits. Memory allocation profiling is disabled!\n",
>> - mod->name, NR_UNUSED_PAGEFLAG_BITS);
>> + pr_warn_once("With module %s there are too many tags to fit in %d page flag bits. Memory allocation profiling is disabled!\n",
>> + mod->name, NR_UNUSED_PAGEFLAG_BITS);
>> + release_module_tags(mod, false);
>> + return ERR_PTR(-EAGAIN);
>> }
>>
>> grow_res = vm_module_tags_populate();
>
This has already been fixed by the commit below:
https://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm.git/commit/?id=4cd27d57fd9468491f2ea48cee93e233c55edda8
Thanks
Best Regards
Hao
next prev parent reply other threads:[~2026-09-03 6:17 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-02 8:17 [PATCH v7 0/4] alloc_tag and module codetag section fixes Hao Ge
2026-09-02 8:17 ` [PATCH v7 1/4] alloc_tag: move release_module_tags() above reserve_module_tags() Hao Ge
2026-09-02 8:34 ` sashiko-bot
2026-09-02 8:18 ` [PATCH v7 2/4] module: introduce SH_ENTSIZE_STANDALONE for separately allocated sections Hao Ge
2026-09-02 8:33 ` sashiko-bot
2026-09-03 6:00 ` Hao Ge
2026-09-04 15:25 ` Petr Pavlu
2026-09-04 16:10 ` Petr Pavlu
2026-09-02 8:18 ` [PATCH v7 3/4] module: allocate codetag sections before the regular module layout Hao Ge
2026-09-02 8:36 ` sashiko-bot
2026-09-03 6:17 ` Hao Ge [this message]
2026-09-02 8:18 ` [PATCH v7 4/4] alloc_tag: release the reservation when populate fails Hao Ge
2026-09-02 8:38 ` sashiko-bot
2026-09-02 22:05 ` [PATCH v7 0/4] alloc_tag and module codetag section fixes Andrew Morton
2026-09-03 6:30 ` Hao Ge
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=920be24a-f8be-4388-b1bc-6bad0cfbb178@linux.dev \
--to=hao.ge@linux.dev \
--cc=akpm@linux-foundation.org \
--cc=linux-modules@vger.kernel.org \
--cc=petr.pavlu@suse.com \
--cc=sashiko-bot@kernel.org \
--cc=surenb@google.com \
/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