Hi all, On Fri, 17 May 2024 09:23:47 +1000 Stephen Rothwell <sfr@xxxxxxxxxxxxxxxx> wrote: > > On Fri, 12 Apr 2024 12:04:21 +1000 Stephen Rothwell <sfr@xxxxxxxxxxxxxxxx> wrote: > > > > Today's linux-next merge of the modules tree got a conflict in: > > > > kernel/module/main.c > > > > between commit: > > > > 58782d7a7ccd ("lib: prevent module unloading if memory is not freed") > > > > from the mm-unstable branch of the mm tree and commit: > > > > a4ee8c9b86bd ("module: make module_memory_{alloc,free} more self-contained") > > > > from the modules tree. > > > > This is now a conflict between the mm-stable tree and Linus' tree. The actual final resolution (due to more patches) is below. -- Cheers, Stephen Rothwell diff --cc kernel/module/main.c index 91e185607d4b,2d25eebc549d..d18a94b973e1 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@@ -56,8 -56,8 +56,9 @@@ #include <linux/dynamic_debug.h> #include <linux/audit.h> #include <linux/cfi.h> + #include <linux/codetag.h> #include <linux/debugfs.h> +#include <linux/execmem.h> #include <uapi/linux/module.h> #include "internal.h" @@@ -1188,50 -1198,32 +1189,54 @@@ void __weak module_arch_freeing_init(st { } -static bool mod_mem_use_vmalloc(enum mod_mem_type type) +static int module_memory_alloc(struct module *mod, enum mod_mem_type type) { - return IS_ENABLED(CONFIG_ARCH_WANTS_MODULES_DATA_IN_VMALLOC) && - mod_mem_type_is_core_data(type); -} + unsigned int size = PAGE_ALIGN(mod->mem[type].size); + enum execmem_type execmem_type; + void *ptr; -static void *module_memory_alloc(unsigned int size, enum mod_mem_type type) -{ - if (mod_mem_use_vmalloc(type)) - return vzalloc(size); - return module_alloc(size); + mod->mem[type].size = size; + + if (mod_mem_type_is_data(type)) + execmem_type = EXECMEM_MODULE_DATA; + else + execmem_type = EXECMEM_MODULE_TEXT; + + ptr = execmem_alloc(execmem_type, size); + if (!ptr) + return -ENOMEM; + + /* + * The pointer to these blocks of memory are stored on the module + * structure and we keep that around so long as the module is + * around. We only free that memory when we unload the module. + * Just mark them as not being a leak then. The .init* ELF + * sections *do* get freed after boot so we *could* treat them + * slightly differently with kmemleak_ignore() and only grey + * them out as they work as typical memory allocations which + * *do* eventually get freed, but let's just keep things simple + * and avoid *any* false positives. + */ + kmemleak_not_leak(ptr); + + memset(ptr, 0, size); + mod->mem[type].base = ptr; + + return 0; } - static void module_memory_free(struct module *mod, enum mod_mem_type type) -static void module_memory_free(void *ptr, enum mod_mem_type type, ++static void module_memory_free(struct module *mod, enum mod_mem_type type, + bool unload_codetags) { + void *ptr = mod->mem[type].base; + + if (!unload_codetags && mod_mem_type_is_core_data(type)) + return; + - if (mod_mem_use_vmalloc(type)) - vfree(ptr); - else - module_memfree(ptr); + execmem_free(ptr); } - static void free_mod_mem(struct module *mod) + static void free_mod_mem(struct module *mod, bool unload_codetags) { for_each_mod_mem_type(type) { struct module_memory *mod_mem = &mod->mem[type]; @@@ -1242,12 -1234,13 +1247,12 @@@ /* Free lock-classes; relies on the preceding sync_rcu(). */ lockdep_free_key_range(mod_mem->base, mod_mem->size); if (mod_mem->size) - module_memory_free(mod, type); - module_memory_free(mod_mem->base, type, - unload_codetags); ++ module_memory_free(mod, type, unload_codetags); } /* MOD_DATA hosts mod, so free it at last */ lockdep_free_key_range(mod->mem[MOD_DATA].base, mod->mem[MOD_DATA].size); - module_memory_free(mod, MOD_DATA); - module_memory_free(mod->mem[MOD_DATA].base, MOD_DATA, unload_codetags); ++ module_memory_free(mod, MOD_DATA, unload_codetags); } /* Free a module, remove from lists, etc. */ @@@ -2287,7 -2309,7 +2299,7 @@@ static int move_module(struct module *m return 0; out_enomem: for (t--; t >= 0; t--) - module_memory_free(mod, t); - module_memory_free(mod->mem[t].base, t, true); ++ module_memory_free(mod, t, true); return ret; }
Attachment:
pgpCk2v9HGz4s.pgp
Description: OpenPGP digital signature