* [PATCH AUTOSEL 6.18-5.10] powercap: fix sscanf() error return value handling
@ 2025-12-23 10:05 Sasha Levin
2025-12-23 10:05 ` [PATCH AUTOSEL 6.18-5.10] powercap: fix race condition in register_control_type() Sasha Levin
0 siblings, 1 reply; 2+ messages in thread
From: Sasha Levin @ 2025-12-23 10:05 UTC (permalink / raw)
To: patches, stable
Cc: Sumeet Pawnikar, Rafael J. Wysocki, Sasha Levin, rafael, linux-pm
From: Sumeet Pawnikar <sumeet4linux@gmail.com>
[ Upstream commit efc4c35b741af973de90f6826bf35d3b3ac36bf1 ]
Fix inconsistent error handling for sscanf() return value check.
Implicit boolean conversion is used instead of explicit return
value checks. The code checks if (!sscanf(...)) which is incorrect
because:
1. sscanf returns the number of successfully parsed items
2. On success, it returns 1 (one item passed)
3. On failure, it returns 0 or EOF
4. The check 'if (!sscanf(...))' is wrong because it treats
success (1) as failure
All occurrences of sscanf() now uses explicit return value check.
With this behavior it returns '-EINVAL' when parsing fails (returns
0 or EOF), and continues when parsing succeeds (returns 1).
Signed-off-by: Sumeet Pawnikar <sumeet4linux@gmail.com>
[ rjw: Subject and changelog edits ]
Link: https://patch.msgid.link/20251207151549.202452-1-sumeet4linux@gmail.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
Looking at this commit carefully to assess its suitability for stable
backporting.
## Commit Analysis
### 1. COMMIT MESSAGE ANALYSIS
The commit fixes incorrect error handling for `sscanf()` return value
checks in the powercap subsystem. The message claims that `if
(!sscanf(...))` is wrong because:
- `sscanf()` returns the number of successfully parsed items
- On success: returns 1
- On failure: returns 0 or EOF (typically -1)
### 2. CODE CHANGE ANALYSIS
Three identical changes in `drivers/powercap/powercap_sys.c`:
```c
// Before:
if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id))
// After:
if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1)
```
Let me trace through the bug:
- When `sscanf()` returns 0 (no match): `!0` = 1 (true) → error path
taken ✓
- When `sscanf()` returns 1 (success): `!1` = 0 (false) → continues ✓
- When `sscanf()` returns EOF (-1): `!(-1)` = 0 (false) → **error path
NOT taken** ✗
The critical issue is the EOF case. If `sscanf()` returns EOF (e.g.,
empty string input), the check passes incorrectly and execution
continues with an **uninitialized `id` variable**. This then leads to:
```c
if (id >= power_zone->const_id_cnt) // garbage comparison
return -EINVAL;
pconst = &power_zone->constraints[id]; // POTENTIAL OUT-OF-BOUNDS
ACCESS
```
### 3. CLASSIFICATION
This is a **bug fix** that prevents:
- Potential out-of-bounds array access
- Use of uninitialized variable
- Possible kernel crash or memory corruption in edge cases
Not a feature addition, code cleanup, or optimization.
### 4. SCOPE AND RISK ASSESSMENT
- **Lines changed**: 3 lines (identical pattern)
- **Files affected**: 1 file
- **Risk**: Extremely low - the change only makes the check stricter and
more explicit
- **Could break anything?**: No - the new check `!= 1` is strictly more
conservative than `!`
### 5. USER IMPACT
The powercap subsystem manages:
- Intel RAPL power capping
- Power domain constraints
- Used by tools like powertop, thermald
While the EOF triggering condition is rare (would require malformed
attribute names), the consequence (OOB access) could be severe.
### 6. STABILITY INDICATORS
- Signed-off by Rafael J. Wysocki (Intel power management maintainer)
- Self-contained fix with no dependencies
- The powercap subsystem has existed since kernel 3.13
### 7. DEPENDENCY CHECK
- No dependencies on other commits
- Simple standalone fix
- Code exists in all active stable trees
## Summary
**What it fixes**: Incorrect sscanf error handling that could allow
execution with uninitialized data, potentially leading to out-of-bounds
array access.
**Why it matters for stable**: While the triggering condition (EOF from
sscanf) is rare, the fix prevents a potential memory safety issue. The
change is trivially correct with zero regression risk.
**Meets stable criteria**:
- ✓ Obviously correct (explicit `!= 1` check is cleaner and more robust)
- ✓ Fixes a real bug (uninitialized variable use, potential OOB access)
- ✓ Small and contained (3 identical one-line changes)
- ✓ No new features
- ✓ No dependencies
**Risk vs benefit**: The benefit (preventing potential memory
corruption) outweighs the near-zero risk of regression.
**YES**
drivers/powercap/powercap_sys.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c
index d14b36b75189..1ff369880beb 100644
--- a/drivers/powercap/powercap_sys.c
+++ b/drivers/powercap/powercap_sys.c
@@ -68,7 +68,7 @@ static ssize_t show_constraint_##_attr(struct device *dev, \
int id; \
struct powercap_zone_constraint *pconst;\
\
- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \
+ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) \
return -EINVAL; \
if (id >= power_zone->const_id_cnt) \
return -EINVAL; \
@@ -93,7 +93,7 @@ static ssize_t store_constraint_##_attr(struct device *dev,\
int id; \
struct powercap_zone_constraint *pconst;\
\
- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \
+ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) \
return -EINVAL; \
if (id >= power_zone->const_id_cnt) \
return -EINVAL; \
@@ -162,7 +162,7 @@ static ssize_t show_constraint_name(struct device *dev,
ssize_t len = -ENODATA;
struct powercap_zone_constraint *pconst;
- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id))
+ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1)
return -EINVAL;
if (id >= power_zone->const_id_cnt)
return -EINVAL;
--
2.51.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH AUTOSEL 6.18-5.10] powercap: fix race condition in register_control_type()
2025-12-23 10:05 [PATCH AUTOSEL 6.18-5.10] powercap: fix sscanf() error return value handling Sasha Levin
@ 2025-12-23 10:05 ` Sasha Levin
0 siblings, 0 replies; 2+ messages in thread
From: Sasha Levin @ 2025-12-23 10:05 UTC (permalink / raw)
To: patches, stable
Cc: Sumeet Pawnikar, Rafael J. Wysocki, Sasha Levin, rafael, linux-pm
From: Sumeet Pawnikar <sumeet4linux@gmail.com>
[ Upstream commit 7bda1910c4bccd4b8d4726620bb3d6bbfb62286e ]
The device becomes visible to userspace via device_register()
even before it fully initialized by idr_init(). If userspace
or another thread tries to register a zone immediately after
device_register(), the control_type_valid() will fail because
the control_type is not yet in the list. The IDR is not yet
initialized, so this race condition causes zone registration
failure.
Move idr_init() and list addition before device_register()
fix the race condition.
Signed-off-by: Sumeet Pawnikar <sumeet4linux@gmail.com>
[ rjw: Subject adjustment, empty line added ]
Link: https://patch.msgid.link/20251205190216.5032-1-sumeet4linux@gmail.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
This confirms the race condition mechanism:
1. `control_type_valid()` walks `powercap_cntrl_list` to validate
control types (lines 329-345)
2. Called at `powercap_register_zone()` entry (line 497)
3. **Race window**: After `device_register()` but before
`list_add_tail()`, any zone registration fails because the
control_type isn't in the list yet
### 8. FINAL ASSESSMENT
| Criteria | Assessment |
|----------|------------|
| Fixes a real bug | ✅ Race condition causing zone registration failure
|
| Obviously correct | ✅ Classic init-before-publish pattern |
| Small and contained | ✅ ~20 lines in one function |
| No new features | ✅ Only reorders existing code |
| No new APIs | ✅ No userspace-visible changes |
| Low regression risk | ✅ Standard pattern, proper error handling |
| Affects stable users | ✅ Powercap used on many Intel systems |
**Why this matters to stable users:**
- Intel RAPL (Running Average Power Limit) uses powercap
- Common on laptops and servers for power management
- Race can cause power capping features to fail during boot/module load
- This is an existing bug that has been present since powercap was
introduced
**Risk vs Benefit:**
- **Benefit**: Fixes a real race that causes functional failures
- **Risk**: Very low - the fix follows standard kernel patterns and adds
proper cleanup
- **Trade-off**: Strongly favors backporting
**Concerns:**
- No dependencies on other commits
- The change is self-contained and should apply cleanly to stable trees
- The powercap subsystem has existed since kernel 3.11, so applicable to
all current stable trees
The fix is small, surgical, obviously correct, and addresses a real race
condition that can cause user-visible failures. It meets all stable
kernel criteria.
**YES**
drivers/powercap/powercap_sys.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c
index 4112a0097338..d14b36b75189 100644
--- a/drivers/powercap/powercap_sys.c
+++ b/drivers/powercap/powercap_sys.c
@@ -625,17 +625,23 @@ struct powercap_control_type *powercap_register_control_type(
INIT_LIST_HEAD(&control_type->node);
control_type->dev.class = &powercap_class;
dev_set_name(&control_type->dev, "%s", name);
- result = device_register(&control_type->dev);
- if (result) {
- put_device(&control_type->dev);
- return ERR_PTR(result);
- }
idr_init(&control_type->idr);
mutex_lock(&powercap_cntrl_list_lock);
list_add_tail(&control_type->node, &powercap_cntrl_list);
mutex_unlock(&powercap_cntrl_list_lock);
+ result = device_register(&control_type->dev);
+ if (result) {
+ mutex_lock(&powercap_cntrl_list_lock);
+ list_del(&control_type->node);
+ mutex_unlock(&powercap_cntrl_list_lock);
+
+ idr_destroy(&control_type->idr);
+ put_device(&control_type->dev);
+ return ERR_PTR(result);
+ }
+
return control_type;
}
EXPORT_SYMBOL_GPL(powercap_register_control_type);
--
2.51.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2025-12-23 10:05 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-12-23 10:05 [PATCH AUTOSEL 6.18-5.10] powercap: fix sscanf() error return value handling Sasha Levin
2025-12-23 10:05 ` [PATCH AUTOSEL 6.18-5.10] powercap: fix race condition in register_control_type() Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).