On Thu, Jun 04, 2026 at 01:04:46PM +0200, Petr Pavlu wrote:
> Historically, various parameter-handling code kept pointers into
> module::args, most notably the charp support. However, in 2009,
> commit e180a6b7759a ("param: fix charp parameters set via sysfs") changed
> charp parameters to kstrdup() the input string as well. As a result,
> module::args now mostly wastes memory.
>
> The last users that still pointed into module::args have now been cleaned
> up, so remove this data.
>
> Signed-off-by: Petr Pavlu <[email protected]>
> ---
> include/linux/module.h | 4 ----
> kernel/module/main.c | 15 ++++++++-------
> 2 files changed, 8 insertions(+), 11 deletions(-)
>
> diff --git a/include/linux/module.h b/include/linux/module.h
> index 7566815fabbe..96cc98568eea 100644
> --- a/include/linux/module.h
> +++ b/include/linux/module.h
> @@ -477,10 +477,6 @@ struct module {
> struct module_notes_attrs *notes_attrs;
> #endif
>
> - /* The command line arguments (may be mangled). People like
> - keeping pointers to this stuff */
> - char *args;
> -
> #ifdef CONFIG_SMP
> /* Per-cpu data. */
> void __percpu *percpu;
> diff --git a/kernel/module/main.c b/kernel/module/main.c
> index 46dd8d25a605..528690ba160b 100644
> --- a/kernel/module/main.c
> +++ b/kernel/module/main.c
> @@ -1458,7 +1458,6 @@ static void free_module(struct module *mod)
>
> /* This may be empty, but that's OK */
> module_arch_freeing_init(mod);
> - kfree(mod->args);
> percpu_modfree(mod);
>
> free_mod_mem(mod);
> @@ -3425,7 +3424,7 @@ static int load_module(struct load_info *info, const
> char __user *uargs,
> struct module *mod;
> bool module_allocated = false;
> long err = 0;
> - char *after_dashes;
> + char *args = NULL, *after_dashes;
>
> /*
> * Do the signature check (if any) first. All that
> @@ -3523,9 +3522,9 @@ static int load_module(struct load_info *info, const
> char __user *uargs,
> flush_module_icache(mod);
>
> /* Now copy in args */
> - mod->args = strndup_user(uargs, ~0UL >> 1);
> - if (IS_ERR(mod->args)) {
> - err = PTR_ERR(mod->args);
> + args = strndup_user(uargs, ~0UL >> 1);
> + if (IS_ERR(args)) {
> + err = PTR_ERR(args);
> goto free_arch_cleanup;
> }
>
> @@ -3546,7 +3545,7 @@ static int load_module(struct load_info *info, const
> char __user *uargs,
> mod->async_probe_requested = async_probe;
>
> /* Module is ready to execute: parsing args may do that. */
> - after_dashes = parse_args(mod->name, mod->args, mod->kp, mod->num_kp,
> + after_dashes = parse_args(mod->name, args, mod->kp, mod->num_kp,
> -32768, 32767, mod,
> unknown_module_param_cb);
> if (IS_ERR(after_dashes)) {
> @@ -3556,6 +3555,8 @@ static int load_module(struct load_info *info, const
> char __user *uargs,
> pr_warn("%s: parameters '%s' after `--' ignored\n",
> mod->name, after_dashes);
> }
> + kfree(args);
> + args = NULL;
>
> /* Link in to sysfs. */
> err = mod_sysfs_setup(mod, info, mod->kp, mod->num_kp);
> @@ -3597,7 +3598,7 @@ static int load_module(struct load_info *info, const
> char __user *uargs,
> ddebug_cleanup:
> ftrace_release_mod(mod);
> synchronize_rcu();
> - kfree(mod->args);
> + kfree(args);
> free_arch_cleanup:
> module_arch_cleanup(mod);
> free_modinfo:
> --
> 2.54.0
>
LGTM.
Reviewed-by: Aaron Tomlin <[email protected]>
--
Aaron Tomlin