From d1d68505da0903592aad12e8711dd1bdcae388e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Mon, 26 Jan 2015 11:00:31 +0100 Subject: [PATCH] Do not accept contract code with gas greater than 2^63. Keep gas counter in int64 type. --- libevmjit-cpp/JitVM.cpp | 7 +++++-- libevmjit/Arith256.cpp | 1 - libevmjit/RuntimeData.h | 2 +- libevmjit/RuntimeManager.cpp | 16 +++++++++------- 4 files changed, 15 insertions(+), 11 deletions(-) diff --git a/libevmjit-cpp/JitVM.cpp b/libevmjit-cpp/JitVM.cpp index 10133a0dc..c8ee74899 100644 --- a/libevmjit-cpp/JitVM.cpp +++ b/libevmjit-cpp/JitVM.cpp @@ -13,7 +13,9 @@ bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const&, uint64_t) { using namespace jit; - m_data.elems[RuntimeData::Gas] = eth2llvm(m_gas); + if (m_gas > std::numeric_limits::max()) + BOOST_THROW_EXCEPTION(OutOfGas()); // Do not accept requests with gas > 2^63 (int64 max) + m_data.elems[RuntimeData::Address] = eth2llvm(fromAddress(_ext.myAddress)); m_data.elems[RuntimeData::Caller] = eth2llvm(fromAddress(_ext.caller)); m_data.elems[RuntimeData::Origin] = eth2llvm(fromAddress(_ext.origin)); @@ -28,6 +30,7 @@ bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const&, uint64_t) m_data.code = _ext.code.data(); m_data.codeSize = _ext.code.size(); m_data.callDataSize = _ext.data.size(); + m_data.gas = static_cast(m_gas); auto env = reinterpret_cast(&_ext); auto exitCode = m_engine.run(_ext.code, &m_data, env); @@ -49,7 +52,7 @@ bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const&, uint64_t) break; } - m_gas = llvm2eth(m_data.elems[RuntimeData::Gas]); + m_gas = m_data.gas; // TODO: Remove m_gas field return {std::get<0>(m_engine.returnData), std::get<1>(m_engine.returnData)}; } diff --git a/libevmjit/Arith256.cpp b/libevmjit/Arith256.cpp index adb6cf9d5..14af9923c 100644 --- a/libevmjit/Arith256.cpp +++ b/libevmjit/Arith256.cpp @@ -65,7 +65,6 @@ llvm::Value* Arith256::mul(llvm::Value* _arg1, llvm::Value* _arg2) llvm::Value* Arith256::div(llvm::Value* _arg1, llvm::Value* _arg2) { - //return Endianness::toNative(m_builder, binaryOp(m_div, Endianness::toBE(m_builder, _arg1), Endianness::toBE(m_builder, _arg2))); return binaryOp(m_div, _arg1, _arg2); } diff --git a/libevmjit/RuntimeData.h b/libevmjit/RuntimeData.h index 75d9c0267..3b128f317 100644 --- a/libevmjit/RuntimeData.h +++ b/libevmjit/RuntimeData.h @@ -14,7 +14,6 @@ struct RuntimeData { enum Index { - Gas, Address, Caller, Origin, @@ -37,6 +36,7 @@ struct RuntimeData byte const* code = nullptr; uint64_t codeSize = 0; uint64_t callDataSize = 0; + int64_t gas = 0; }; /// VM Environment (ExtVM) opaque type diff --git a/libevmjit/RuntimeManager.cpp b/libevmjit/RuntimeManager.cpp index ec4334390..75802593f 100644 --- a/libevmjit/RuntimeManager.cpp +++ b/libevmjit/RuntimeManager.cpp @@ -26,7 +26,8 @@ llvm::StructType* RuntimeManager::getRuntimeDataType() Type::BytePtr, // callData Type::BytePtr, // code Type::Size, // codeSize - Type::Size // callDataSize + Type::Size, // callDataSize + Type::Size, // gas }; type = llvm::StructType::create(elems, "RuntimeData"); } @@ -58,7 +59,6 @@ llvm::Twine getName(RuntimeData::Index _index) switch (_index) { default: return "data"; - case RuntimeData::Gas: return "gas"; case RuntimeData::Address: return "address"; case RuntimeData::Caller: return "caller"; case RuntimeData::Origin: return "origin"; @@ -150,7 +150,6 @@ llvm::Value* RuntimeManager::get(Instruction _inst) switch (_inst) { default: assert(false); return nullptr; - case Instruction::GAS: return get(RuntimeData::Gas); case Instruction::ADDRESS: return get(RuntimeData::Address); case Instruction::CALLER: return get(RuntimeData::Caller); case Instruction::ORIGIN: return get(RuntimeData::Origin); @@ -200,14 +199,17 @@ llvm::Value* RuntimeManager::getJmpBuf() llvm::Value* RuntimeManager::getGas() { - return get(RuntimeData::Gas); + auto ptr = getBuilder().CreateStructGEP(getDataPtr(), 5); + auto value = getBuilder().CreateLoad(ptr, "gas"); + assert(value->getType() == Type::Size); + return getBuilder().CreateZExt(value, Type::Word); } void RuntimeManager::setGas(llvm::Value* _gas) { - llvm::Value* idxList[] = {m_builder.getInt32(0), m_builder.getInt32(0), m_builder.getInt32(RuntimeData::Gas)}; - auto ptr = m_builder.CreateInBoundsGEP(getDataPtr(), idxList, "gasPtr"); - m_builder.CreateStore(_gas, ptr); + auto ptr = getBuilder().CreateStructGEP(getDataPtr(), 5); + auto newGas = getBuilder().CreateTrunc(_gas, Type::Size); + getBuilder().CreateStore(newGas, ptr); } }