Skip to content

Commit

Permalink
smith: Fix an overflowing subtraction in no-traps mode (#827)
Browse files Browse the repository at this point in the history
The logic which fit data segments to always be in-bounds for the
no-traps mode had an underflow when the data segment was larger than the
initial size of memory, so this updates the logic to truncate the data
segment and then additionally refactors the offset-adjustment logic
slightly.
  • Loading branch information
alexcrichton committed Nov 18, 2022
1 parent a436ce0 commit 1095eaf
Showing 1 changed file with 11 additions and 9 deletions.
20 changes: 11 additions & 9 deletions crates/wasm-smith/src/core.rs
Expand Up @@ -1274,7 +1274,7 @@ impl Module {
self.config.min_data_segments(),
self.config.max_data_segments(),
|u| {
let init: Vec<u8> = u.arbitrary()?;
let mut init: Vec<u8> = u.arbitrary()?;

// Passive data can only be generated if bulk memory is enabled.
// Otherwise if there are no memories we *only* generate passive
Expand All @@ -1293,19 +1293,21 @@ impl Module {
u.choose(&choices32)?
};
let mut offset = f(u, mem.minimum, init.len())?;

// If traps are disallowed then truncate the size of the
// data segment to the minimum size of memory to guarantee
// it will fit. Afterwards ensure that the offset of the
// data segment is in-bounds by clamping it to the
if self.config.disallow_traps() {
let max_size = mem.minimum * 64 * 1024;
init.truncate(max_size as usize);
let max_offset = max_size - init.len() as u64;
match &mut offset {
Offset::Const32(x) => {
let m = (mem.minimum * 64 * 1024) - init.len() as u64;
if m < i32::MAX as u64 {
*x = (*x).min(m as i32);
}
*x = (*x as u64).min(max_offset) as i32;
}
Offset::Const64(x) => {
let m = (mem.minimum * 64 * 1024) - init.len() as u64;
if m < i64::MAX as u64 {
*x = (*x).min(m as i64);
}
*x = (*x as u64).min(max_offset) as i64;
}
Offset::Global(_) => unreachable!(),
}
Expand Down

0 comments on commit 1095eaf

Please sign in to comment.