argotorg / argotorg/solcore

No calldata bounds checks

Open
#579 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Haskell
Stars
113
Forks
9
Avg merge
4d 9h
Merged PRs (30d)
1

Description

BUG: generated dispatch validates only the static ABI head. Dynamic offsets,
lengths and element regions are not checked against calldatasize().
EVM calldata reads outside the supplied input yield zeros, so malformed calls can succeed with values the caller never supplied.
```solidity
import std.{*};
import std.dispatch.{*};

contract MalformedDynamicCalldata {
public function echoBytes(value: memory(bytes)) -> memory(bytes) {
return value;
}
public function arrayAt(
items: calldata(array(uint256)),
index: uint256
) -> uint256 {
return items[index];
}
}
```
For comparision ordinary Solidity rejects the same truncated calldata.
```solidity
pragma solidity ^0.8.0;
contract MalformedDynamicCalldataReference {
function echoBytes(bytes memory value) public pure returns (bytes memory) {
return value;
}
function arrayAt(uint256[] calldata items, uint256 index)
public pure returns (uint256) {
return items[index];
}
}
```

SOLUTION: Introduce bounded ABI readers carrying start, cursor, and end positions.
Bounds checks are needed in these ABI paths:
- do_exec: establish the calldata payload range and validate the complete static head.
- CalldataWordReader.read/copyToMem/advance: enforce bounds and prevent pointer overflow centrally.
- Scalar decoders (uint256, bytes32, bytes4, bool, address): ensure each 32-byte word exists, preferably through the
reader.
- decodeBytesLike: validate the head, dynamic offset, length word, padded payload end, and arithmetic.
- Tuple/ABITuple decoders: validate head-offset arithmetic and dynamic tuple offsets.
- Memory DynArray decoder: validate the offset, length, element-head region, multiplication, and every element.
- Calldata array decoder: validate the offset and length word before creating its lazy handle.
- abiArrayLength: ensure the handle points to an available length word.
- abiArrayGet: validate index multiplication, complete element table/region, and dynamic element offsets.
- WordReader.copyToMem: ensure the entire source range exists before copying.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by locating do_exec, CalldataWordReader, WordReader, and the listed ABI decoders, then trace how generated dispatch establishes calldata ranges. Check malformed dynamic calldata cases such as truncated bytes and arrays, and verify every listed reader and decoder rejects missing words, overflowed ranges, and invalid offsets instead of returning zero-filled values.

Written by the indexing model from the issue text.

Assessment

Tech stack
haskell, solidity
Domain
compilers, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.