From 1e83520f1d83e8582eb7730050889aeb3f2f78d5 Mon Sep 17 00:00:00 2001 From: Jonathan Becker Date: Mon, 30 Dec 2024 12:44:13 -0500 Subject: [PATCH] fix(vm): fix "safe" conversions from `Uint<256>` to `usize` (#546) --- crates/vm/src/core/vm.rs | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/crates/vm/src/core/vm.rs b/crates/vm/src/core/vm.rs index 36defe66..16502219 100644 --- a/crates/vm/src/core/vm.rs +++ b/crates/vm/src/core/vm.rs @@ -832,14 +832,13 @@ impl VM { let offset = self.stack.pop()?.value; let size = self.stack.pop()?.value; - // Safely convert U256 to usize - // Note: clamping to 8 words here, since we dont actually use the return data - let dest_offset: usize = dest_offset.try_into()?; - let offset: usize = offset.try_into()?; - let size: usize = size.try_into()?; + // Safely convert U256 to usize, clamping to calldata length + let dest_offset: usize = dest_offset.try_into().unwrap_or(usize::MAX); + let offset: usize = offset.try_into().unwrap_or(usize::MAX); + let size: usize = size.try_into().unwrap_or(usize::MAX); // clamp values to calldata length - let end_offset_clamped = (offset + size).min(self.calldata.len()); + let end_offset_clamped = offset.saturating_add(size).min(self.calldata.len()); let size = size.min(self.calldata.len()); let mut value = @@ -877,13 +876,12 @@ impl VM { let offset = self.stack.pop()?.value; let size = self.stack.pop()?.value; - // Safely convert U256 to usize - // Note: clamping to 8 words here, since we dont actually use the return data - let dest_offset: usize = dest_offset.try_into()?; - let offset: usize = offset.try_into()?; - let size: usize = size.try_into()?; + // Safely convert U256 to usize, clamping to bytecode length + let dest_offset: usize = dest_offset.try_into().unwrap_or(usize::MAX); + let offset: usize = offset.try_into().unwrap_or(usize::MAX); + let size: usize = size.try_into().unwrap_or(usize::MAX); - let value_offset_safe = (offset + size).min(self.bytecode.len()); + let value_offset_safe = offset.saturating_add(size).min(self.bytecode.len()); let mut value = self.bytecode.get(offset..value_offset_safe).unwrap_or(&[]).to_owned(); @@ -934,7 +932,6 @@ impl VM { let size = self.stack.pop()?.value; // Safely convert U256 to usize - // Note: clamping to 8 words here, since we dont actually use the return data let dest_offset: usize = dest_offset.try_into()?; let size: usize = size.try_into()?; @@ -974,7 +971,6 @@ impl VM { let size = self.stack.pop()?.value; // Safely convert U256 to usize - // Note: clamping to 8 words here, since we dont actually use the return data let dest_offset: usize = dest_offset.try_into()?; let size: usize = size.try_into()?; @@ -1118,7 +1114,7 @@ impl VM { let pc = self.stack.pop()?.value; // Safely convert U256 to u128 - let pc: u128 = pc.try_into()?; + let pc: u128 = pc.try_into().unwrap_or(u128::MAX); // Check if JUMPDEST is valid and throw with 790 if not (invalid jump destination) if (pc <= @@ -1148,7 +1144,7 @@ impl VM { let condition = self.stack.pop()?.value; // Safely convert U256 to u128 - let pc: u128 = pc.try_into()?; + let pc: u128 = pc.try_into().unwrap_or(u128::MAX); if !condition.eq(&U256::from(0u8)) { // Check if JUMPDEST is valid and throw with 790 if not (invalid jump @@ -1197,12 +1193,12 @@ impl VM { let offset = self.stack.pop()?.value; let size = self.stack.pop()?.value; - // Safely convert U256 to usize - // Note: clamping to 8 words here, since we dont actually use the return data - let dest_offset: usize = dest_offset.try_into()?; - let offset: usize = offset.try_into()?; - let size: usize = size.try_into()?; - let value_offset_safe = (offset + size) + // Safely convert U256 to usize, clamping to memory length + let dest_offset: usize = dest_offset.try_into().unwrap_or(u128::MAX as usize); + let offset: usize = offset.try_into().unwrap_or(u128::MAX as usize); + let size: usize = size.try_into().unwrap_or(u128::MAX as usize); + let value_offset_safe = offset + .saturating_add(size) .min(self.memory.size().try_into().expect("failed to convert u128 to usize")); let mut value =