Uninitialized stack reads in create_pa_curve when training bins lack samples
Summary
create_pa_curve declares fixed-size stack arrays theta[NUM_BIN+1] x_est[NUM_BIN+1] y[NUM_BIN+1] without initialization (lines 1398-1404). First loop (1449-1498) only writes x_est[bin+1] y[bin+1] theta[bin+1] when accum_cnt[bin] > thresh_accum_cnt(16). If fewer than 6 bins meet threshold (max_index<6) then theta[1..5] x_est[6] y[6] remain uninitialized stack garbage. These used unconditionally: theta[1..5] summed into theta_low_bin (line 1504-1506) x_est[6]==x_est[3] compared (line 1524) x_est[6]-x_est[3] used in division (line 1527-1529). Uninitialized values propagate through signed multiply/shift chains (lines 1598-1604 1618-1619 1647-1648 1717-1727) causing signed-integer-overflow UB. Final pa_in[] clamped to 1400 pa_angle to +-150 masked to 11 bits written to hardware so no register overflow/crash. Attacker: malicious/faulty ath adapter or real adapter under abnormal RF conditions (no signal/jammed loopback) where insufficient bins accumulate >16 samples. Impact: UB garbage PA predistortion table degraded TX linearity/RF compliance. No kernel crash no memory corruption no info leak values stay kernel-internal. CONTRIBUTED vendored code upstream owns fix. [VERIFIED pass2: reproduced - dual stack primings 0xC3 vs 0x5A flip g_fxp_ext 0 from 2 to 5 proving uninit theta x_est y flow into PA predistortion outputs, clamped before hardware; OS_MEMZERO fix-validated; contrib upstream owns]
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-2259 Β· 3 files| File | Type | Description | Size | |
|---|---|---|---|---|
| run_baseline_curve.log | run-log | g_fxp_ext[0]=2 (prime C3) vs 5 (prime 5A) | 2.0 KB | view raw |
| fix.diff | suggested-fix | OS_MEMZERO estimator arrays at entry | 1.3 KB | view raw |
| ../DF-2258/rig/dfpaprd_harness.c | trigger-source | shared verbatim rig (curve modes) | 10.3 KB | view raw |
Fix verification
fixedConfirmed kernel references
Detail
Evidence (decisive lines)
run_baseline_curve.log: prime=0xc3 g_fxp_ext[0]=2 vs prime=0x5a g_fxp_ext[0]=5, same inputs; control rows show index-0 uninit as well
PoC changes
Authored priming A/B rig (shared with DF-2258 harness)
Verified recommended fix
OS_MEMZERO every NUM_BIN+1 estimator array at create_pa_curve entry
Verdict
Verbatim create_pa_curve executed with identical sparse training inputs under two kernel-stack primings (0xC3 vs 0x5A): g_fxp_ext[0] changes 2 -> 5, proving uninitialized stack slots (theta[1..5]/x_est[6]/y[6] unwritten when fewer than 6 bins exceed the 16-sample threshold; index-0 entries never written at all) flow into the PA predistortion outputs. Outputs are clamped before hardware writes: no crash, no disclosure; impact is garbage-derived radio calibration from faulty/malicious ath training data. Contributed code; upstream owns the fix (zeroing patch documented). A/B: Fixed-kernel sparse runs identical under both primings (g_fxp_ext[0]=2 both; baseline 2 vs 5): uninit-stack influence eliminated.
No comments yet.