Skip to content

Commit 2ce4424

Browse files
committed
fix: critical safety fixes in wasm_executor
- Fix output pointer extraction: use u32 masking instead of i32 cast to prevent sign-extension on high-address pointers - Check output size BEFORE read_memory to prevent OOM on malicious WASM modules returning huge out_len - Fix allocate_input fallback: require minimum 4KB headroom to prevent writing over WASM stack/globals at low memory offsets
1 parent d9e5421 commit 2ce4424

File tree

1 file changed

+16
-13
lines changed

1 file changed

+16
-13
lines changed

bins/validator-node/src/wasm_executor.rs

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -194,29 +194,29 @@ impl WasmChallengeExecutor {
194194
_ => anyhow::anyhow!("WASM evaluate call failed: {}", e),
195195
})?;
196196

197-
let out_len = (result >> 32) as i32;
198-
let out_ptr = result as i32;
197+
let out_len = ((result >> 32) & 0xFFFF_FFFF) as u32;
198+
let out_ptr = (result & 0xFFFF_FFFF) as u32;
199199

200200
if out_ptr == 0 && out_len == 0 {
201201
return Err(anyhow::anyhow!(
202202
"WASM evaluate returned null pointer, deserialization failed inside module"
203203
));
204204
}
205205

206-
let output_bytes = instance
207-
.read_memory(out_ptr as usize, out_len as usize)
208-
.map_err(|e| {
209-
anyhow::anyhow!("Failed to read evaluation output from WASM memory: {}", e)
210-
})?;
211-
212-
if output_bytes.len() > MAX_EVALUATION_OUTPUT_SIZE {
206+
if out_len as usize > MAX_EVALUATION_OUTPUT_SIZE {
213207
return Err(anyhow::anyhow!(
214208
"EvaluationOutput size {} exceeds maximum allowed {}",
215-
output_bytes.len(),
209+
out_len,
216210
MAX_EVALUATION_OUTPUT_SIZE
217211
));
218212
}
219213

214+
let output_bytes = instance
215+
.read_memory(out_ptr as usize, out_len as usize)
216+
.map_err(|e| {
217+
anyhow::anyhow!("Failed to read evaluation output from WASM memory: {}", e)
218+
})?;
219+
220220
let output: EvaluationOutput = bincode::deserialize(&output_bytes)
221221
.context("Failed to deserialize EvaluationOutput from WASM module")?;
222222

@@ -368,12 +368,15 @@ impl WasmChallengeExecutor {
368368
}
369369

370370
let mem_size = instance.memory().data_size(instance.store());
371-
let offset = mem_size.saturating_sub(input_data.len() + 1024);
372-
if offset == 0 {
371+
let required = input_data.len() + 1024;
372+
if mem_size < required + 4096 {
373373
return Err(anyhow::anyhow!(
374-
"WASM module has insufficient memory for input data"
374+
"WASM module has insufficient memory for input data ({} < {})",
375+
mem_size,
376+
required + 4096
375377
));
376378
}
379+
let offset = mem_size - required;
377380
Ok(offset as i32)
378381
}
379382

0 commit comments

Comments
 (0)