Re: [PATCH 1/3] platform/x86/amd: hfi: Fix a use-after-free when unloading the driver
From: Mario Limonciello
Date: Mon Sep 21 2026 - 13:56:57 EST
On 9/21/26 12:04, Mario Limonciello wrote:
amd_hfi_probe() registers CPU hotplug callbacks with
cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, ...) and schedules the static
sched_amd_hfi_itmt_work work item, but amd_hfi_remove() tears down
neither. The dynamically assigned hotplug state returned by
cpuhp_setup_state() is discarded, so cpuhp_remove_state() can never be
called, and the pending work is never cancelled.
After the module is unloaded and its memory is freed, any subsequent CPU
hotplug event or execution of the scheduled work dereferences the stale
callback and work function pointers, resulting in a use-after-free and
kernel panic.
Store the hotplug state returned by cpuhp_setup_state() and, on removal,
call cpuhp_remove_state() to unregister the callbacks and
cancel_work_sync() to flush the scheduled work before the module memory
goes away.
Cc: stable@xxxxxxxxxxxxxxx
Fixes: bb20421c05fc ("platform/x86: hfi: Add online and offline callback support")
Signed-off-by: Mario Limonciello <mario.limonciello@xxxxxxx>
Reported-by: Sashiko <sashiko-bot@xxxxxxxxxx>
Closes: https://sashiko.dev/#/bug/linux-e2a43433-2732-4af4-97f1-ec320a95f087> ---
drivers/platform/x86/amd/hfi/hfi.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/platform/x86/amd/hfi/hfi.c b/drivers/platform/x86/amd/hfi/hfi.c
index e0ebcb0c4acde..e1c776b71f3e6 100644
--- a/drivers/platform/x86/amd/hfi/hfi.c
+++ b/drivers/platform/x86/amd/hfi/hfi.c
@@ -76,6 +76,8 @@ struct amd_hfi_data {
struct amd_shmem_info *shmem;
struct dentry *dbgfs_dir;
+
+ int cpuhp_state;
};
/**
@@ -244,6 +246,8 @@ static void amd_hfi_remove(struct platform_device *pdev)
{
struct amd_hfi_data *dev = platform_get_drvdata(pdev);
+ cpuhp_remove_state(dev->cpuhp_state);
+ cancel_work_sync(&sched_amd_hfi_itmt_work);
debugfs_remove_recursive(dev->dbgfs_dir);
}
@@ -494,6 +498,7 @@ static int amd_hfi_probe(struct platform_device *pdev)
amd_hfi_online, amd_hfi_offline);
if (ret < 0)
return ret;
+ amd_hfi_data->cpuhp_state = ret;
schedule_work(&sched_amd_hfi_itmt_work);