Thank you for your contribution! Sashiko AI review found 1 potential issue(s) 
to consider:
- [Medium] Per-cpu counters for allocation tags are permanently leaked on 
module unload if the tag area overflows during module load.
--

commit 2a544bb32bf3bb065ea63ecd36207973b4aa45cd
Author: Hao Ge <[email protected]>

module: allocate codetag sections before the regular module layout

This commit modifies the module loader to decide and allocate codetag
sections in one pass before the regular module layout. If the separate
allocation overflows, it returns -EAGAIN so the section can fall back to
being a regular module section, allowing the module to still load.

Link: 
https://lore.kernel.org/all/[email protected]/ [1]

> diff --git a/kernel/module/main.c b/kernel/module/main.c
> index 9b495571d8074..c3ea72e1e412f 100644
> --- a/kernel/module/main.c
> +++ b/kernel/module/main.c

[ ... ]

> @@ -2947,6 +2908,49 @@ static bool blacklisted(const char *module_name)
> +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: Medium]
Could this fallback mechanism cause a permanent leak of per-cpu counters
when the module is unloaded?

When the module tag area overflows, reserve_module_tags() returns -EAGAIN,
and this code catches it to allow the section to load normally. Later in the
load process, the tags are still processed, and per-cpu counters are
unconditionally allocated for each tag:

mm/alloc_tag.c:load_module() {
    ...
    tag->counters = alloc_percpu(struct alloc_tag_counters);
    ...
}

However, on module unload, release_module_tags() searches the mod_area_mt
maple tree to find the module. Since the codetag section fell back to
standard memory and was never added to the maple tree, the search fails:

mm/alloc_tag.c:release_module_tags() {
    ...
    if (!val) /* module not found */
        goto out;
    ...
}

This early exit completely bypasses clean_unused_counters(), leaving all
those per-cpu counters allocated during load permanently leaked. Is there a
way to ensure the counters are cleaned up even when the codetag section
falls back to standard memory?

> +             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);
> +             else
> +                     memset(dest, 0, shdr->sh_size);
> +             shdr->sh_addr = (unsigned long)dest;
> +             shdr->sh_entsize = SH_ENTSIZE_STANDALONE;
> +     }
> +
> +     return 0;
> +}

-- 
Sashiko AI review ยท 
https://sashiko.dev/#/patchset/[email protected]?part=3

Reply via email to