mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 17:47:41 +02:00
drm/amd/pm: Add empty string validation to sysfs store functions
Discovery: Fuzzing for secure supply chain requirements
Tool: amd_fuzzing_sysfs (IGT test)
The AMDGPU power management sysfs store functions accept whitespace-only
strings when they should reject them with -EINVAL. This was discovered via
systematic fuzzing of sysfs interfaces crossing the user/kernel trust
boundary.
Affected functions:
- amdgpu_set_power_dpm_force_performance_level (power_dpm_force_performance_level)
- amdgpu_set_power_dpm_state (power_dpm_state)
- amdgpu_set_pp_power_profile_mode (pp_power_profile_mode)
- amdgpu_read_mask (used by pp_dpm_sclk/mclk/fclk/socclk/pcie)
- amdgpu_set_pp_features (pp_features)
Impact:
- Whitespace-only writes (e.g., "\n", " ") can cause unexpected behavior
- Better input validation at user/kernel trust boundary
- Defense-in-depth improvement
Root Cause:
The sysfs_streq() function matches whitespace-only strings against empty
string, allowing invalid input to be processed.
Fix:
Add explicit validation at the start of each affected store function:
if (count == 0 || sysfs_streq(buf, ""))
return -EINVAL;
This rejects whitespace-only inputs before they are processed. Note that
write() calls with count=0 (truly empty strings) are handled by the VFS
layer before reaching the sysfs .store() callback - the VFS returns 0
(success) without calling the kernel function. This is POSIX-compliant
behavior and cannot be changed at the kernel driver level.
What This Patch Fixes:
- Whitespace-only strings: "\n", " ", " ", etc. are now rejected
- Defense-in-depth: Explicit validation at trust boundary
- Code clarity: Intent to reject invalid input is explicit
What This Patch Cannot Fix:
- write(fd, "", 0) returning success - this is VFS layer behavior
- Fuzzer tests for empty strings (count=0) will still report "accepted"
because the VFS handles this before the kernel callback
Test Results After Fix:
- Whitespace strings ("\n", " ") now properly rejected
- Empty string tests (count=0) still show as "accepted" due to VFS behavior
- Overall improvement in input validation robustness
- No impact on valid inputs
This is a defense-in-depth improvement that hardens input validation
even though VFS layer behavior prevents catching all edge cases.
Tested: amd_fuzzing_sysfs IGT test
Cc: Christian König <christian.koenig@amd.com>
Cc: Alex Deucher <alexander.deucher@amd.com>
Cc: Jesse Zhang <jesse.zhang@amd.com>
Signed-off-by: Vitaly Prosyak <vitaly.prosyak@amd.com>
Acked-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
This commit is contained in:
parent
08ac3a7879
commit
c872fc0538
|
|
@ -244,6 +244,10 @@ static ssize_t amdgpu_set_power_dpm_state(struct device *dev,
|
|||
enum amd_pm_state_type state;
|
||||
int ret;
|
||||
|
||||
/* Reject empty/whitespace strings - fuzzing found this is not validated */
|
||||
if (count == 0 || sysfs_streq(buf, ""))
|
||||
return -EINVAL;
|
||||
|
||||
if (sysfs_streq(buf, "battery"))
|
||||
state = POWER_STATE_TYPE_BATTERY;
|
||||
else if (sysfs_streq(buf, "balanced"))
|
||||
|
|
@ -364,6 +368,10 @@ static ssize_t amdgpu_set_power_dpm_force_performance_level(struct device *dev,
|
|||
enum amd_dpm_forced_level level;
|
||||
int ret = 0;
|
||||
|
||||
/* Reject empty/whitespace strings - fuzzing found this is not validated */
|
||||
if (count == 0 || sysfs_streq(buf, ""))
|
||||
return -EINVAL;
|
||||
|
||||
if (sysfs_streq(buf, "low"))
|
||||
level = AMD_DPM_FORCED_LEVEL_LOW;
|
||||
else if (sysfs_streq(buf, "high"))
|
||||
|
|
@ -902,6 +910,10 @@ static ssize_t amdgpu_set_pp_features(struct device *dev,
|
|||
uint64_t featuremask;
|
||||
int ret;
|
||||
|
||||
/* Reject empty/whitespace strings - fuzzing found kstrtou64 accepts "" as 0 */
|
||||
if (count == 0 || sysfs_streq(buf, ""))
|
||||
return -EINVAL;
|
||||
|
||||
ret = kstrtou64(buf, 0, &featuremask);
|
||||
if (ret)
|
||||
return -EINVAL;
|
||||
|
|
@ -1027,6 +1039,10 @@ static ssize_t amdgpu_read_mask(const char *buf, size_t count, uint32_t *mask)
|
|||
|
||||
*mask = 0;
|
||||
|
||||
/* Reject empty/whitespace strings - fuzzing found this is not validated */
|
||||
if (count == 0 || sysfs_streq(buf, ""))
|
||||
return -EINVAL;
|
||||
|
||||
bytes = min(count, sizeof(buf_cpy) - 1);
|
||||
memcpy(buf_cpy, buf, bytes);
|
||||
buf_cpy[bytes] = '\0';
|
||||
|
|
@ -1378,6 +1394,10 @@ static ssize_t amdgpu_set_pp_power_profile_mode(struct device *dev,
|
|||
long int profile_mode = 0;
|
||||
const char delimiter[3] = {' ', '\n', '\0'};
|
||||
|
||||
/* Reject empty/whitespace strings - fuzzing found this is not validated */
|
||||
if (count == 0 || sysfs_streq(buf, ""))
|
||||
return -EINVAL;
|
||||
|
||||
tmp[0] = *(buf);
|
||||
tmp[1] = '\0';
|
||||
ret = kstrtol(tmp, 0, &profile_mode);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user