diff --git a/CHANGELOG.md b/CHANGELOG.md index bc6dc9de20..c4e7ad8dd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ #### Upcoming Changes +* fix: Check overflow in cairo pie address calculation [#1945](https://github.com/lambdaclass/cairo-vm/pull/1945) + #### [2.0.0-rc5] - 2025-02-24 * fix: Fix Cairo Pie limiting the number of segments to 2^16 [#1960](https://github.com/lambdaclass/cairo-vm/pull/1960) diff --git a/vm/src/vm/runners/cairo_pie.rs b/vm/src/vm/runners/cairo_pie.rs index 53a0ad185f..ca6960e2d4 100644 --- a/vm/src/vm/runners/cairo_pie.rs +++ b/vm/src/vm/runners/cairo_pie.rs @@ -582,7 +582,17 @@ pub(super) mod serde_impl { let mut res = Vec::with_capacity(mem_cap); for ((segment, offset), value) in values.iter() { - let mem_addr = ADDR_BASE + *segment as u64 * OFFSET_BASE + *offset as u64; + // mem_addr = ADDR_BASE + segment * OFFSET_BASE + offset + let mem_addr = (*segment as u64) + .checked_mul(OFFSET_BASE) + .and_then(|n| n.checked_add(ADDR_BASE)) + .and_then(|n| n.checked_add(*offset as u64)) + .ok_or_else(|| { + serde::ser::Error::custom(format!( + "failed to serialize address: {segment}:{offset}" + )) + })?; + res.extend_from_slice(mem_addr.to_le_bytes().as_ref()); match value { // Serializes RelocatableValue(little endian): @@ -939,6 +949,17 @@ mod test { ); } + #[test] + fn serialize_cairo_pie_memory_with_overflow() { + let memory = CairoPieMemory(vec![ + ((0, 0), MaybeRelocatable::Int(0.into())), + ((0, 1), MaybeRelocatable::Int(1.into())), + ((usize::MAX, 0), MaybeRelocatable::Int(2.into())), + ]); + + serde_json::to_value(memory).unwrap_err(); + } + #[rstest] #[cfg(feature = "std")] #[case(include_bytes!("../../../../cairo_programs/fibonacci.json"), "fibonacci")]