β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-2259

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)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-2259 Β· 3 files
FileTypeDescriptionSize
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

fixed
↓ fix.diffper-fix-DF-2259

Confirmed 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.