From nobody Thu Apr 9 17:25:21 2026 Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 69F5239281C for ; Fri, 6 Mar 2026 12:57:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772801835; cv=none; b=XvGxCmU6ZwZis1KyN+C23GctxB3eYQttWLs9rqLCzfxun6AeSFYvshHk67KGk8/RP9pwP8pVF+n1sELPCFH7zcRcTUU3s+h6lw4FDRes1/riYNQSjClx+IZYWLNPzXe/++LUJalzk2aMEtTJNLL5P7qraDjhrBfgNBNCkOpPC04= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1772801835; c=relaxed/simple; bh=OV5otnRgS/S+0kH9qEdyT/f7wV5xTxdVSISYKq4ifD0=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=gc3aSgj46wjvJ4oh4bYanFSOu8zR3hIADGh0VwefQUajKj9gbDsffFqbJy0NCdtErQSv5rVX0gvH7SoQQJVFkPxuaPXRRTnRJWRd1yEn/2mjXFLNKA46XZfF7JxfoDjASNthn90DUWUqIbNA08XSWBGZt2y/xCdPY1p/FOoRVas= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=suse.com; spf=pass smtp.mailfrom=suse.com; dkim=pass (2048-bit key) header.d=suse.com header.i=@suse.com header.b=VIp3AoLm; arc=none smtp.client-ip=209.85.128.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=suse.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=suse.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=suse.com header.i=@suse.com header.b="VIp3AoLm" Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-48336a6e932so59097485e9.3 for ; Fri, 06 Mar 2026 04:57:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=suse.com; s=google; t=1772801831; x=1773406631; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=umr5xt4p3qMVQx4ufWCasqFVTfl1J7n+hKybDwFVeVA=; b=VIp3AoLmLtwrvzBWBiosFqWEw3+yNbzDL4GXyKc635ZZDs1omjVfyZTOkPEpiTrfEH tFDZqoVXSowP/yx1BPBrYEeUl/At0S3gmDACKgOdxz22M6Nszcosv9i8Zf53wxrI4fY8 PymwH//SAriJTBP7WYNNKUdVphOgBiLmH8twEWa0zWczVjCEahoGnEdEu1ckA3RNuFnA pVHUuyF+VOH3psRWGA+Ezom+edGN6oHvn/uSx1JyrxwaWkrwtt7xFLA+E8zQK8Mp3FGF 0uIjFD5pWPsaj4RA7RJKI4fVEpyNPzipWz1p9TCYtB/ZkackqN5UW97iPSOUrRgU7ESw q5oA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1772801831; x=1773406631; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=umr5xt4p3qMVQx4ufWCasqFVTfl1J7n+hKybDwFVeVA=; b=ngX9zUFV8MCx7d3e6L4DFRco2WmiorMT452XrHbW0eT1bwTKW3y9Di7ZGFiIZ0I2b6 R5uGIzT5TnsxM2yDjzyR7ALgFoR0ZZ2fcD7BkSIyQrU3ByKl7u7yn9zoCnIXk1F9zdN7 Ot0tUsW+jKVHSfnWYBsUA5lSNFXPJ5OJXV6skv5lkOH/wlYuSiL5/jwjnPyqlZ7eIZqv d8K+bYx+4udMtfS+8eFKtDbZF0/LgZSvGBEt6a2MwJnjgEMCwlPyXNRpBHIjMKF4M9fi GQpUsYtO/sWXlWs7i7RXUcK+tE/q+JJvCXFkpyWlBs3rabGh/vQXF2+yqvn/izZbnxCh egxw== X-Forwarded-Encrypted: i=1; AJvYcCVNKYRNc/CiaqAxUkT8ZPP63tdcqvwzDq3KluxznF2gGAcU5/HypXVzAdc09d+s5IQNy6T8hDYfk3TnRcQ=@vger.kernel.org X-Gm-Message-State: AOJu0YxtxSLxKV0XTO9Q/7SNoyrzzH8jWvMd1vAyb8tK5oim6loJMOz5 7KZJ2Mp8TUVTP/rq9gjbVAGxG6xB5Djv2ySSg0/npXDZodaAS7oxRt8zdTuXaOCEYos= X-Gm-Gg: ATEYQzzyf+WRWoQTRbN1oRLzJ1/Ui+vvWkJTJqB7V5tDHm43pNKQoCI9rUwqa0OWqud wRYXD2J5V51jHCRrpmbO+8BV4ii5USzy7/xtnD4+J7AR3r5kEAwK51sjIbGuQ9gR/+or9rIsc6Q uVVNGoFYcP1/52jKqP/h+McpUE3O18Yw9SlazcYqKrCb5jl1ky2ZO4kxrs37e+Q76O11J16egdo HHyPhQ3er3yBFBJ6IXSVzA9rmt/CfhvhoZBPgu/TLDuoMglz7amlmxjmcUBEzeBIGYSY/389goh kLsgyAdTo/AylIEBY374v6dihyKgsYhG4+rbho9NwS1gDgve7taXYLGMv1oVOwkgb/iyWb5x8kP kdVqfh1tv7xbGVLfiXduYZsg4ZKrxipXG4sl9+TGBbYOBt0zh9ganBSaclwsndCzo2iUhuR6go2 i0jB6FKx+0VttaM50RssVybrAtzOBegUEhwSOLmtQs X-Received: by 2002:a05:600c:8b8b:b0:47e:e20e:bbb2 with SMTP id 5b1f17b1804b1-4852691884fmr35674595e9.7.1772801831558; Fri, 06 Mar 2026 04:57:11 -0800 (PST) Received: from zovi.suse.cz (nat2.prg.suse.com. [195.250.132.146]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4851fb4257csm181381215e9.15.2026.03.06.04.57.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 06 Mar 2026 04:57:11 -0800 (PST) From: Petr Pavlu To: Luis Chamberlain , Petr Pavlu , Daniel Gomez , Sami Tolvanen Cc: Aaron Tomlin , Greg Kroah-Hartman , "Rafael J. Wysocki" , Danilo Krummrich , linux-modules@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] module: Fix freeing of charp module parameters when CONFIG_SYSFS=n Date: Fri, 6 Mar 2026 12:10:52 +0100 Message-ID: <20260306125457.1377402-1-petr.pavlu@suse.com> X-Mailer: git-send-email 2.53.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" When setting a charp module parameter, the param_set_charp() function allocates memory to store a copy of the input value. Later, when the module is potentially unloaded, the destroy_params() function is called to free this allocated memory. However, destroy_params() is available only when CONFIG_SYSFS=3Dy, otherwise only a dummy variant is present. In the unlikely case that the kernel is configured with CONFIG_MODULES=3Dy and CONFIG_SYSFS=3Dn, this results in a memory leak of charp values when a module is unloaded. Fix this issue by making destroy_params() always available when CONFIG_MODULES=3Dy. Rename the function to module_destroy_params() to clari= fy that it is intended for use by the module loader. Fixes: e180a6b7759a ("param: fix charp parameters set via sysfs") Signed-off-by: Petr Pavlu --- include/linux/moduleparam.h | 12 ++++-------- kernel/module/main.c | 4 ++-- kernel/params.c | 27 ++++++++++++++++++--------- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h index 7d22d4c4ea2e..6283665ec614 100644 --- a/include/linux/moduleparam.h +++ b/include/linux/moduleparam.h @@ -426,14 +426,10 @@ extern char *parse_args(const char *name, void *arg, parse_unknown_fn unknown); =20 /* Called by module remove. */ -#ifdef CONFIG_SYSFS -extern void destroy_params(const struct kernel_param *params, unsigned num= ); -#else -static inline void destroy_params(const struct kernel_param *params, - unsigned num) -{ -} -#endif /* !CONFIG_SYSFS */ +#ifdef CONFIG_MODULES +extern void module_destroy_params(const struct kernel_param *params, + unsigned num); +#endif =20 /* All the helper functions */ /* The macros to do compile-time type checking stolen from Jakub diff --git a/kernel/module/main.c b/kernel/module/main.c index c3ce106c70af..ef2e2130972f 100644 --- a/kernel/module/main.c +++ b/kernel/module/main.c @@ -1408,7 +1408,7 @@ static void free_module(struct module *mod) module_unload_free(mod); =20 /* Free any allocated parameters. */ - destroy_params(mod->kp, mod->num_kp); + module_destroy_params(mod->kp, mod->num_kp); =20 if (is_livepatch_module(mod)) free_module_elf(mod); @@ -3519,7 +3519,7 @@ static int load_module(struct load_info *info, const = char __user *uargs, mod_sysfs_teardown(mod); coming_cleanup: mod->state =3D MODULE_STATE_GOING; - destroy_params(mod->kp, mod->num_kp); + module_destroy_params(mod->kp, mod->num_kp); blocking_notifier_call_chain(&module_notify_list, MODULE_STATE_GOING, mod); klp_module_going(mod); diff --git a/kernel/params.c b/kernel/params.c index 7188a12dbe86..1a436c9d6140 100644 --- a/kernel/params.c +++ b/kernel/params.c @@ -745,15 +745,6 @@ void module_param_sysfs_remove(struct module *mod) } #endif =20 -void destroy_params(const struct kernel_param *params, unsigned num) -{ - unsigned int i; - - for (i =3D 0; i < num; i++) - if (params[i].ops->free) - params[i].ops->free(params[i].arg); -} - struct module_kobject * __init_or_module lookup_or_create_module_kobject(const char *name) { @@ -985,3 +976,21 @@ static int __init param_sysfs_builtin_init(void) late_initcall(param_sysfs_builtin_init); =20 #endif /* CONFIG_SYSFS */ + +#ifdef CONFIG_MODULES + +/* + * module_destroy_params - free all parameters for one module + * @params: module parameters (array) + * @num: number of module parameters + */ +void module_destroy_params(const struct kernel_param *params, unsigned num) +{ + unsigned int i; + + for (i =3D 0; i < num; i++) + if (params[i].ops->free) + params[i].ops->free(params[i].arg); +} + +#endif /* CONFIG_MODULES */ base-commit: c107785c7e8dbabd1c18301a1c362544b5786282 --=20 2.53.0