|
3 | 3 | #![allow(unreachable_code)]
|
4 | 4 | #![allow(clippy::arithmetic_side_effects)]
|
5 | 5 |
|
| 6 | +#[cfg(feature = "dynamic-frames")] |
| 7 | +use solana_program::program_memory::sol_memcmp; |
6 | 8 | use {
|
7 | 9 | solana_program::{
|
8 | 10 | account_info::AccountInfo,
|
@@ -1456,19 +1458,38 @@ fn process_instruction<'a>(
|
1456 | 1458 | heap[8..pos].fill(42);
|
1457 | 1459 |
|
1458 | 1460 | // Check that the stack is zeroed too.
|
1459 |
| - // |
| 1461 | + let stack = unsafe { |
| 1462 | + slice::from_raw_parts_mut( |
| 1463 | + MM_STACK_START as *mut u8, |
| 1464 | + MAX_CALL_DEPTH * STACK_FRAME_SIZE, |
| 1465 | + ) |
| 1466 | + }; |
| 1467 | + |
| 1468 | + #[cfg(not(feature = "dynamic-frames"))] |
1460 | 1469 | // We don't know in which frame we are now, so we skip a few (10) frames at the start
|
1461 | 1470 | // which might have been used by the current call stack. We check that the memory for
|
1462 | 1471 | // the 10..MAX_CALL_DEPTH frames is zeroed. Then we write a sentinel value, and in the
|
1463 | 1472 | // next nested invocation check that it's been zeroed.
|
1464 |
| - let stack = |
1465 |
| - unsafe { slice::from_raw_parts_mut(MM_STACK_START as *mut u8, 0x100000000) }; |
| 1473 | + // |
| 1474 | + // When we don't have dynamic stack frames, the stack grows from lower addresses |
| 1475 | + // to higher addresses, so we compare accordingly. |
1466 | 1476 | for i in 10..MAX_CALL_DEPTH {
|
1467 | 1477 | let stack = &mut stack[i * STACK_FRAME_SIZE..][..STACK_FRAME_SIZE];
|
1468 | 1478 | assert!(stack == &ZEROS[..STACK_FRAME_SIZE], "stack not zeroed");
|
1469 | 1479 | stack.fill(42);
|
1470 | 1480 | }
|
1471 | 1481 |
|
| 1482 | + #[cfg(feature = "dynamic-frames")] |
| 1483 | + // When we have dynamic frames, the stack grows from the higher addresses, so we |
| 1484 | + // compare from zero until the beginning of a function frame. |
| 1485 | + // We have 64 * 4096 = 262.144 bytes of stack space, and we consider around 4096 |
| 1486 | + // already used by the current function and previous calls. We are considering a |
| 1487 | + // little less than 63 * 4096 = 258.048 bytes to be zeroed. |
| 1488 | + { |
| 1489 | + assert_eq!(sol_memcmp(stack, &ZEROS, 257900), 0); |
| 1490 | + stack[..257900].fill(42); |
| 1491 | + } |
| 1492 | + |
1472 | 1493 | // Recurse to check that the stack and heap are zeroed.
|
1473 | 1494 | //
|
1474 | 1495 | // We recurse until we go over max CPI depth and error out. Stack and heap allocations
|
|
0 commit comments