diff options
| author | Mario Limonciello <mario.limonciello@amd.com> | 2026-09-21 21:23:47 -0500 |
|---|---|---|
| committer | Mario Limonciello <superm1@kernel.org> | 2026-10-01 12:52:31 -0500 |
| commit | b667a680917119827916bf2eb7d6f8de9c47531f (patch) | |
| tree | 7dcb6952db943da72694ec3d07675654e896e106 /tools/perf/scripts/python | |
| parent | b400642c5e93863ec17ea15fcbd3efc81c299531 (diff) | |
cpufreq/amd-pstate: Fix TOCTOU when changing driver mode via sysfs
amd_pstate_update_status() evaluates mode_state_machine[cppc_state]
[mode_idx] before taking amd_pstate_driver_lock, and then re-evaluates it
again once the lock is held. cppc_state is global and only stable under
the lock, so concurrent sysfs writes race:
CPU 0 CPU 1
----- -----
// cppc_state == A, mode == B
if (mode_state_machine[A][B]) // sees non-NULL
if (mode_state_machine[A][B])
guard(&amd_pstate_driver_lock);
mode_state_machine[A][B](B);
cppc_state = B;
guard(&amd_pstate_driver_lock);
// cppc_state is now B
mode_state_machine[B][B](B); // NULL -> NULL deref
The re-read under the lock can resolve to a self-transition (NULL
pointer, immediate NULL deref) or to an unexpected transition that
redundantly runs amd_pstate_driver_cleanup(), double-freeing
current_pstate_driver->attr.
Take the lock first, then read cppc_state and resolve the transition
function exactly once into a local before calling it, so the check and
the call observe the same state.
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/bug/linux-f86ff3a6-55df-4eef-8e4d-62ac270dba25
Fixes: 6f0b13f16f7a ("cpufreq/amd-pstate: Overhaul locking")
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Reviewed-by: K Prateek Nayak <kprateek.nayak@amd.com>
Tested-by: K Prateek Nayak <kprateek.nayak@amd.com>
Link: https://lore.kernel.org/r/20260922022347.1270746-1-mario.limonciello@amd.com
Signed-off-by: Mario Limonciello <superm1@kernel.org>
Diffstat (limited to 'tools/perf/scripts/python')
0 files changed, 0 insertions, 0 deletions
