Commit 95765dfc authored by mbaxter's avatar mbaxter Committed by GitHub

cannon: Handle unaligned futex addresses (#11929)

* cannon: Update tests for futex unaligned memory behavior

* cannon: Align futex-related addresses when they are set

* cannon: Run lint and semver tasks

* cannon: Add wakeup traversal tests with unaligend addresses

* cannon: Don't panic if ThreadState.FutexAddr is unaligned

* cannon: Run semver lock task

* cannon: Cleanup stray whitespace
parent 717330e9
......@@ -105,15 +105,16 @@ func (m *InstrumentedState) handleSyscall() error {
return nil
case exec.SysFutex:
// args: a0 = addr, a1 = op, a2 = val, a3 = timeout
effAddr := a0 & 0xFFffFFfc
switch a1 {
case exec.FutexWaitPrivate:
m.memoryTracker.TrackMemAccess(a0)
mem := m.state.Memory.GetMemory(a0)
m.memoryTracker.TrackMemAccess(effAddr)
mem := m.state.Memory.GetMemory(effAddr)
if mem != a2 {
v0 = exec.SysErrorSignal
v1 = exec.MipsEAGAIN
} else {
thread.FutexAddr = a0
thread.FutexAddr = effAddr
thread.FutexVal = a2
if a3 == 0 {
thread.FutexTimeoutStep = exec.FutexNoTimeout
......@@ -126,7 +127,7 @@ func (m *InstrumentedState) handleSyscall() error {
case exec.FutexWakePrivate:
// Trigger thread traversal starting from the left stack until we find one waiting on the wakeup
// address
m.state.Wakeup = a0
m.state.Wakeup = effAddr
// Don't indicate to the program that we've woken up a waiting thread, as there are no guarantees.
// The woken up thread should indicate this in userspace.
v0 = 0
......@@ -255,8 +256,9 @@ func (m *InstrumentedState) mipsStep() error {
m.onWaitComplete(thread, true)
return nil
} else {
m.memoryTracker.TrackMemAccess(thread.FutexAddr)
mem := m.state.Memory.GetMemory(thread.FutexAddr)
effAddr := thread.FutexAddr & 0xFFffFFfc
m.memoryTracker.TrackMemAccess(effAddr)
mem := m.state.Memory.GetMemory(effAddr)
if thread.FutexVal == mem {
// still got expected value, continue sleeping, try next thread.
m.preemptThread(thread)
......
......@@ -144,8 +144,8 @@
"sourceCodeHash": "0xba4674e1846afbbc708877332a38dfabd4b8d1e48ce07d8ebf0a45c9f27f16b0"
},
"src/cannon/MIPS2.sol": {
"initCodeHash": "0xdaed5d70cc84a53f224c28f24f8eef26d5d53dfba9fdc4f1b28c3b231b974e53",
"sourceCodeHash": "0x4026eb7ae7b303ec4c3c2880e14e260dbcfc0b4290459bcd22994cfed8655f80"
"initCodeHash": "0xd9da47f735b7a655a25ae0e867b467620a2cb537eb65d184a361f5ea4174d384",
"sourceCodeHash": "0x3a6d83a7d46eb267f6778f8ae116383fe3c14ad553d90b6c761fafeef22ae29c"
},
"src/cannon/PreimageOracle.sol": {
"initCodeHash": "0x801e52f9c8439fcf7089575fa93272dfb874641dbfc7d82f36d979c987271c0b",
......
......@@ -57,8 +57,8 @@ contract MIPS2 is ISemver {
}
/// @notice The semantic version of the MIPS2 contract.
/// @custom:semver 1.0.0-beta.9
string public constant version = "1.0.0-beta.9";
/// @custom:semver 1.0.0-beta.10
string public constant version = "1.0.0-beta.10";
/// @notice The preimage oracle contract.
IPreimageOracle internal immutable ORACLE;
......@@ -175,7 +175,7 @@ contract MIPS2 is ISemver {
// Don't allow regular execution until we resolved if we have woken up any thread.
if (state.wakeup != sys.FUTEX_EMPTY_ADDR) {
if (state.wakeup == thread.futexAddr) {
// completed wake traverssal
// completed wake traversal
// resume execution on woken up thread
state.wakeup = sys.FUTEX_EMPTY_ADDR;
return outputState();
......@@ -431,15 +431,15 @@ contract MIPS2 is ISemver {
return outputState();
} else if (syscall_no == sys.SYS_FUTEX) {
// args: a0 = addr, a1 = op, a2 = val, a3 = timeout
uint32 effAddr = a0 & 0xFFffFFfc;
if (a1 == sys.FUTEX_WAIT_PRIVATE) {
uint32 mem = MIPSMemory.readMem(
state.memRoot, a0 & 0xFFffFFfc, MIPSMemory.memoryProofOffset(MEM_PROOF_OFFSET, 1)
);
uint32 mem =
MIPSMemory.readMem(state.memRoot, effAddr, MIPSMemory.memoryProofOffset(MEM_PROOF_OFFSET, 1));
if (mem != a2) {
v0 = sys.SYS_ERROR_SIGNAL;
v1 = sys.EAGAIN;
} else {
thread.futexAddr = a0;
thread.futexAddr = effAddr;
thread.futexVal = a2;
thread.futexTimeoutStep = a3 == 0 ? sys.FUTEX_NO_TIMEOUT : state.step + sys.FUTEX_TIMEOUT_STEPS;
// Leave cpu scalars as-is. This instruction will be completed by `onWaitComplete`
......@@ -449,7 +449,7 @@ contract MIPS2 is ISemver {
} else if (a1 == sys.FUTEX_WAKE_PRIVATE) {
// Trigger thread traversal starting from the left stack until we find one waiting on the wakeup
// address
state.wakeup = a0;
state.wakeup = effAddr;
// Don't indicate to the program that we've woken up a waiting thread, as there are no guarantees.
// The woken up thread should indicate this in userspace.
v0 = 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment