simd: '0219' title: Stricter ABI and Runtime Constraints authors:
Removing pitfalls and foot-guns from the ABI (including syscalls) and runtime.
There are a couple of interactions between dApps and the virtual machine which are currently allowed but make no sense and are even dangerous for dApps:
AccountInfo structures which the program
runtime never serializedAccountInfo structures can be overwritten by CPI during CPI, causing
complex side effectsFurthermore, at the moment all validator implementations have to copy (and compare) data in and out of the virtual memory of the virtual machine. There are four possible account data copy paths:
By restricting the allowed behavior of dApps we enable the validator to map account payload data directly, avoiding copies and compares.
None.
The memory regions are (in ABI v0 and v1):
0x100000000..0x200000000)0x200000000..0x300000000)0x300000000..0x400000000)The payload address space of an account is the range in the serialized input
region (0x400000000..0x500000000) which covers the payload and optionally the
10 KiB resize padding (if not a loader-v1 program), but not the accounts
metadata.
0x200000000..0x400000000,
otherwise SyscallError::InvalidPointer must be thrown:
&[AccountInfo] / SolAccountInfo*AccountInfo::data field,
which is a RefCell<&[u8]> in sol_invoke_signed_rustAccountInfo::lamports field,
which is a RefCell<&u64> in sol_invoke_signed_rustSyscallError::InvalidPointer must be thrown:
AccountInfo::key / SolAccountInfo::keyAccountInfo::owner / SolAccountInfo::ownerAccountInfo::lamports / SolAccountInfo::lamportsAccountInfo::data::ptr / SolAccountInfo::dataMemory accesses (both by the program and by syscalls) which span across memory mapping regions are considered access violations. Accesses to multiple regions (e.g. by memcpy syscalls) have to be split into multiple separate accesses, one for each region.
For all memory accesses to the payload address space of an account which is flagged as writable and owned by the currently executed program, check that:
InstructionError::InvalidRealloc must be thrown.InstructionError::InvalidRealloc must be thrown.For loads / read accesses to the payload address space of an account check that:
InstructionError::AccountDataTooSmall must be thrown.For stores / write accesses to the payload address space of an account check that:
InstructionError::ReadonlyDataModified must be thrownInstructionError::ExternalAccountDataModified must be thrown.These restrictions have been extensively tested by replay against MNB. Most of the dApps devs whose dApps would fail have been contacted and had their dApps fixed already.
Programs which used the SDKs account realloc function, which is now deprecated, should upgrade in order to avoid the read-before-write access to uninitialized memory.
None.