diff --git a/src/compiler/evm_frontend/evm_mir_compiler.cpp b/src/compiler/evm_frontend/evm_mir_compiler.cpp index fd3796da..69ee0525 100644 --- a/src/compiler/evm_frontend/evm_mir_compiler.cpp +++ b/src/compiler/evm_frontend/evm_mir_compiler.cpp @@ -984,13 +984,35 @@ void EVMMirBuilder::handleJump(Operand Dest) { MBasicBlock *InvalidJumpBB = getOrCreateExceptionSetBB(ErrorCode::EVMBadJumpDestination); if (Dest.isConstant()) { - uint64_t ConstDest = Dest.getConstValue()[0]; + const auto &ConstValue = Dest.getConstValue(); + if ((ConstValue[3] | ConstValue[2] | ConstValue[1]) != 0) { + createInstruction(true, Ctx, InvalidJumpBB); + addSuccessor(InvalidJumpBB); + return; + } + uint64_t ConstDest = ConstValue[0]; implementConstantJump(ConstDest, InvalidJumpBB); - } else { - U256Inst DestComponents = extractU256Operand(Dest); - MInstruction *JumpTarget = DestComponents[0]; - implementIndirectJump(JumpTarget, InvalidJumpBB); + return; } + + U256Inst DestComponents = extractU256Operand(Dest); + MInstruction *JumpTarget = DestComponents[0]; + MType *MirI64Type = + EVMFrontendContext::getMIRTypeFromEVMType(EVMType::UINT64); + MInstruction *Zero = createIntConstInstruction(MirI64Type, 0); + MInstruction *HighOr = createInstruction( + false, OP_or, MirI64Type, DestComponents[1], DestComponents[2]); + HighOr = createInstruction(false, OP_or, MirI64Type, + HighOr, DestComponents[3]); + MInstruction *HighNonZero = createInstruction( + false, CmpInstruction::Predicate::ICMP_NE, &Ctx.I64Type, HighOr, Zero); + MBasicBlock *ValidJumpBB = createBasicBlock(); + createInstruction(true, Ctx, HighNonZero, InvalidJumpBB, + ValidJumpBB); + addSuccessor(InvalidJumpBB); + addSuccessor(ValidJumpBB); + setInsertBlock(ValidJumpBB); + implementIndirectJump(JumpTarget, InvalidJumpBB); } void EVMMirBuilder::handleJumpI(Operand Dest, Operand Cond) { @@ -1034,9 +1056,28 @@ void EVMMirBuilder::handleJumpI(Operand Dest, Operand Cond) { addSuccessor(FallThroughBB); setInsertBlock(JumpTableBB); if (Dest.isConstant()) { - uint64_t ConstDest = Dest.getConstValue()[0]; - implementConstantJump(ConstDest, InvalidJumpBB); + const auto &ConstValue = Dest.getConstValue(); + if ((ConstValue[3] | ConstValue[2] | ConstValue[1]) != 0) { + createInstruction(true, Ctx, InvalidJumpBB); + addSuccessor(InvalidJumpBB); + } else { + uint64_t ConstDest = ConstValue[0]; + implementConstantJump(ConstDest, InvalidJumpBB); + } } else { + MInstruction *HighOr = createInstruction( + false, OP_or, MirI64Type, DestComponents[1], DestComponents[2]); + HighOr = createInstruction(false, OP_or, MirI64Type, + HighOr, DestComponents[3]); + MInstruction *HighNonZero = createInstruction( + false, CmpInstruction::Predicate::ICMP_NE, &Ctx.I64Type, HighOr, + Zero); + MBasicBlock *ValidJumpBB = createBasicBlock(); + createInstruction(true, Ctx, HighNonZero, InvalidJumpBB, + ValidJumpBB); + addSuccessor(InvalidJumpBB); + addSuccessor(ValidJumpBB); + setInsertBlock(ValidJumpBB); implementIndirectJump(JumpTarget, InvalidJumpBB); } } diff --git a/src/evm/interpreter.cpp b/src/evm/interpreter.cpp index 47976375..496a422f 100644 --- a/src/evm/interpreter.cpp +++ b/src/evm/interpreter.cpp @@ -9,6 +9,7 @@ #include #include +#include using namespace zen; using namespace zen::evm; @@ -335,7 +336,10 @@ void BaseInterpreter::interpret() { } auto Uint256ToUint64 = [](const intx::uint256 &Value) -> uint64_t { - return static_cast(Value & 0xFFFFFFFFFFFFFFFFULL); + if ((Value[3] | Value[2] | Value[1]) != 0) { + return std::numeric_limits::max(); + } + return Value[0]; }; while (Frame->Pc < CodeSize) {