From: "Ilpo Järvinen" <ilpo.jarvinen@linux.intel.com>
To: Marco Scardovi <scardracs@disroot.org>
Cc: corentin.chary@gmail.com, luke@ljones.dev,
denis.benato@linux.dev, Hans de Goede <hansg@kernel.org>,
platform-driver-x86@vger.kernel.org,
LKML <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] platform/x86: asus-armoury: fix Use-After-Free and memory leak in driver init
Date: Wed, 1 Jul 2026 14:01:12 +0300 (EEST) [thread overview]
Message-ID: <f1c70b62-7e5d-7ed3-afbf-b80e3a0f2daf@linux.intel.com> (raw)
In-Reply-To: <20260614163717.74732-1-scardracs@disroot.org>
On Sun, 14 Jun 2026, Marco Scardovi wrote:
> In init_rog_tunables(), if dc_limits are defined and allocating
> dc_rog_tunables fails, the already allocated ac_rog_tunables gets
> freed but the pointer stored in asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_AC]
> is not cleared. Since init_rog_tunables() returns void, the driver
> initialization continues, which can lead to a Use-After-Free (UAF)
> when asus_fw_attr_add() accesses the freed AC tunables pointer.
>
> Additionally, if init_rog_tunables() succeeds but asus_fw_attr_add()
> fails, the allocated tunables are not freed, resulting in a memory leak.
>
> Fix these issues by making init_rog_tunables() return an error code and
> propagating it in asus_fw_init(). On failure, make sure all partially
> allocated tunables are freed and their pointers are cleared to NULL.
>
> Assisted-by: Antigravity:gemini-3.5-flash
> Signed-off-by: Marco Scardovi <scardracs@disroot.org>
> ---
> drivers/platform/x86/asus-armoury.c | 32 ++++++++++++++++++-----------
> 1 file changed, 20 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/platform/x86/asus-armoury.c b/drivers/platform/x86/asus-armoury.c
> index 495dc1e31d40..3a63f960eb3f 100644
> --- a/drivers/platform/x86/asus-armoury.c
> +++ b/drivers/platform/x86/asus-armoury.c
> @@ -989,7 +989,7 @@ static int asus_fw_attr_add(void)
> /* Init / exit ****************************************************************/
>
> /* Set up the min/max and defaults for ROG tunables */
> -static void init_rog_tunables(void)
> +static int init_rog_tunables(void)
> {
> const struct power_limits *ac_limits, *dc_limits;
> struct rog_tunables *ac_rog_tunables = NULL, *dc_rog_tunables = NULL;
> @@ -1000,14 +1000,14 @@ static void init_rog_tunables(void)
> dmi_id = dmi_first_match(power_limits);
> if (!dmi_id) {
> pr_warn("No matching power limits found for this system\n");
> - return;
> + return 0;
> }
>
> /* Get the power data for this system */
> power_data = dmi_id->driver_data;
> if (!power_data) {
> pr_info("No power data available for this system\n");
> - return;
> + return 0;
> }
>
> /* Initialize AC power tunables */
> @@ -1015,7 +1015,7 @@ static void init_rog_tunables(void)
> if (ac_limits) {
> ac_rog_tunables = kzalloc_obj(*asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_AC]);
> if (!ac_rog_tunables)
> - goto err_nomem;
> + return -ENOMEM;
>
> asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_AC] = ac_rog_tunables;
> ac_rog_tunables->power_limits = ac_limits;
> @@ -1063,7 +1063,8 @@ static void init_rog_tunables(void)
> dc_rog_tunables = kzalloc_obj(*asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_DC]);
> if (!dc_rog_tunables) {
> kfree(ac_rog_tunables);
> - goto err_nomem;
> + asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_AC] = NULL;
> + return -ENOMEM;
> }
>
> asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_DC] = dc_rog_tunables;
> @@ -1106,15 +1107,13 @@ static void init_rog_tunables(void)
> pr_debug("No DC PPT limits defined\n");
> }
>
> - return;
> -
> -err_nomem:
> - pr_err("Failed to allocate memory for tunables\n");
> + return 0;
> }
>
> static int __init asus_fw_init(void)
> {
> char *wmi_uid;
> + int err;
>
> wmi_uid = wmi_get_acpi_device_uid(ASUS_WMI_MGMT_GUID);
> if (!wmi_uid)
> @@ -1127,10 +1126,19 @@ static int __init asus_fw_init(void)
> if (!strcmp(wmi_uid, ASUS_ACPI_UID_ASUSWMI))
> return -ENODEV;
>
> - init_rog_tunables();
> + err = init_rog_tunables();
> + if (err)
> + return err;
>
> - /* Must always be last step to ensure data is available */
> - return asus_fw_attr_add();
> + err = asus_fw_attr_add();
> + if (err) {
> + kfree(asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_AC]);
> + asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_AC] = NULL;
> + kfree(asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_DC]);
> + asus_armoury.rog_tunables[ASUS_ROG_TUNABLE_DC] = NULL;
Why do you need to set these to NULL?
I'd also prefer to use goto + rollback path pattern even if there's only
one entry at this point.
--
i.
next prev parent reply other threads:[~2026-07-01 11:01 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-14 16:37 [PATCH] platform/x86: asus-armoury: fix Use-After-Free and memory leak in driver init Marco Scardovi
2026-07-01 11:01 ` Ilpo Järvinen [this message]
2026-07-01 13:25 ` Marco Scardovi
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=f1c70b62-7e5d-7ed3-afbf-b80e3a0f2daf@linux.intel.com \
--to=ilpo.jarvinen@linux.intel.com \
--cc=corentin.chary@gmail.com \
--cc=denis.benato@linux.dev \
--cc=hansg@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=luke@ljones.dev \
--cc=platform-driver-x86@vger.kernel.org \
--cc=scardracs@disroot.org \
/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.