Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5541926

Browse files
committed
fix(security): harden RuvSense pipeline against overflow and numerical instability
- tomography.rs: use checked_mul for nx*ny*nz to prevent integer overflow on adversarial grid configurations - phase_align.rs: add defensive bounds check in mean_phase_on_indices to prevent panic on out-of-range subcarrier indices - multistatic.rs: stabilize softmax in attention_weighted_fusion with max-subtraction to prevent exp() overflow on extreme similarity values Co-Authored-By: claude-flow <[email protected]>
1 parent 37b54d6 commit 5541926

4 files changed

Lines changed: 34 additions & 13 deletions

File tree

rust-port/wifi-densepose-rs/crates/wifi-densepose-signal/src/ruvsense/longitudinal.rs

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -252,15 +252,23 @@ impl PersonalBaseline {
252252

253253
let mut reports = Vec::new();
254254

255-
for &(metric, value) in &summary.metrics {
256-
let stats = self.stats_for_mut(metric);
257-
stats.update(value);
255+
let observation_days = self.observation_days;
258256

259-
if !self.is_ready_at(self.observation_days) {
257+
for &(metric, value) in &summary.metrics {
258+
// Update stats and extract values before releasing the mutable borrow
259+
let (z, baseline_mean, baseline_std) = {
260+
let stats = self.stats_for_mut(metric);
261+
stats.update(value);
262+
let z = stats.z_score(value);
263+
let mean = stats.mean;
264+
let std = stats.std_dev();
265+
(z, mean, std)
266+
};
267+
268+
if !self.is_ready_at(observation_days) {
260269
continue;
261270
}
262271

263-
let z = stats.z_score(value);
264272
let idx = Self::metric_index(metric);
265273

266274
if z.abs() > 2.0 {
@@ -288,8 +296,8 @@ impl PersonalBaseline {
288296
direction,
289297
z_score: z,
290298
current_value: value,
291-
baseline_mean: stats.mean,
292-
baseline_std: stats.std_dev(),
299+
baseline_mean,
300+
baseline_std,
293301
sustained_days: self.drift_counters[idx],
294302
level,
295303
timestamp_us,

rust-port/wifi-densepose-rs/crates/wifi-densepose-signal/src/ruvsense/multistatic.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ fn attention_weighted_fusion(
257257
}
258258

259259
// Compute attention weights based on similarity to consensus
260-
let mut weights = vec![0.0_f32; n_nodes];
260+
let mut logits = vec![0.0_f32; n_nodes];
261261
for (n, amp) in amplitudes.iter().enumerate() {
262262
let mut dot = 0.0_f32;
263263
let mut norm_a = 0.0_f32;
@@ -269,10 +269,15 @@ fn attention_weighted_fusion(
269269
}
270270
let denom = (norm_a * norm_b).sqrt().max(1e-12);
271271
let similarity = dot / denom;
272-
weights[n] = (similarity / temperature).exp();
272+
logits[n] = similarity / temperature;
273273
}
274274

275-
// Normalize weights (softmax-style)
275+
// Numerically stable softmax: subtract max to prevent exp() overflow
276+
let max_logit = logits.iter().cloned().fold(f32::NEG_INFINITY, f32::max);
277+
let mut weights = vec![0.0_f32; n_nodes];
278+
for (n, &logit) in logits.iter().enumerate() {
279+
weights[n] = (logit - max_logit).exp();
280+
}
276281
let weight_sum: f32 = weights.iter().sum::<f32>().max(1e-12);
277282
for w in &mut weights {
278283
*w /= weight_sum;

rust-port/wifi-densepose-rs/crates/wifi-densepose-signal/src/ruvsense/phase_align.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,11 @@ fn mean_phase_on_indices(phase: &[f32], indices: &[usize]) -> f32 {
281281
let mut sin_sum = 0.0_f32;
282282
let mut cos_sum = 0.0_f32;
283283
for &i in indices {
284-
sin_sum += phase[i].sin();
285-
cos_sum += phase[i].cos();
284+
// Defensive bounds check: skip out-of-range indices rather than panic
285+
if let Some(&p) = phase.get(i) {
286+
sin_sum += p.sin();
287+
cos_sum += p.cos();
288+
}
286289
}
287290

288291
sin_sum.atan2(cos_sum)

rust-port/wifi-densepose-rs/crates/wifi-densepose-signal/src/ruvsense/tomography.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,12 @@ impl RfTomographer {
199199
));
200200
}
201201

202-
let n_voxels = config.nx * config.ny * config.nz;
202+
let n_voxels = config.nx
203+
.checked_mul(config.ny)
204+
.and_then(|v| v.checked_mul(config.nz))
205+
.ok_or_else(|| TomographyError::InvalidGrid(
206+
format!("Grid dimensions overflow: {}x{}x{}", config.nx, config.ny, config.nz),
207+
))?;
203208

204209
// Precompute weight matrix
205210
let weight_matrix: Vec<Vec<(usize, f64)>> = links

0 commit comments

Comments
 (0)