All of lore.kernel.org
 help / color / mirror / Atom feed
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

  reply	other threads:[~2026-09-03  6:17 UTC|newest]

Thread overview: 18+ 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-07  6:10         ` Hao Ge
2026-09-07 12:17           ` Petr Pavlu
2026-09-08  6:39             ` Hao Ge
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 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.