Skip to content

Commit d0fd98b

Browse files
committed
fix(macos): sanity-bound SMC CPU power so an unmapped chip can't show garbage
The SMC cluster keys are M3-Max-verified; a different Apple die could reuse the keys for something else. Reject an implausible sum (NaN/Inf/negative/>200W) so such a chip falls back to Unavailable instead of a wrong number. IOReport stays first (covers all base dies), and Linux/RAPL + Windows/Scaphandre are untouched.
1 parent a0af60d commit d0fd98b

2 files changed

Lines changed: 22 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,17 @@ and the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
77

88
## [Unreleased]
99

10+
## [2.5.2] - 2026-07-02
11+
12+
### Fixed
13+
- **Guard the Apple SMC CPU-power read against unmapped chips.** The SMC cluster
14+
keys are verified on an M3 Max; on a different Apple die the same keys could
15+
mean something else. `power.cpu` from SMC is now rejected if the sum is
16+
implausible (NaN/Inf, negative, or > 200 W), so such a chip falls back to
17+
Unavailable rather than showing a garbage number. IOReport stays the first
18+
source (covers every base die), so this only affects the Pro/Max SMC fallback —
19+
no change on Linux (RAPL) or Windows (Scaphandre).
20+
1021
## [2.5.1] - 2026-07-02
1122

1223
### Changed

app/internal/helper/smc_darwin.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,10 @@ static double smc_read_key(const char *k, int *found) {
8787
*/
8888
import "C"
8989

90-
import "unsafe"
90+
import (
91+
"math"
92+
"unsafe"
93+
)
9194

9295
// smcReadFloat reads a 4-char AppleSMC float key in watts. ok is true when the
9396
// key exists and read as a float (value may be 0); false when absent or the wrong
@@ -126,5 +129,11 @@ func smcCPUPower() (watts float64, ok bool) {
126129
ok = true
127130
}
128131
}
129-
return watts, ok
132+
// Guard against a chip whose key layout differs: if these keys mean something
133+
// else there, or a float misreads, refuse an implausible CPU figure (NaN/Inf,
134+
// negative, or > 200 W) so we fall back to Unavailable rather than show garbage.
135+
if !ok || math.IsNaN(watts) || math.IsInf(watts, 0) || watts < 0 || watts > 200 {
136+
return 0, false
137+
}
138+
return watts, true
130139
}

0 commit comments

Comments
 (0)