From 045098b29649616285d6f5ba27d1b8610bde4666 Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Sun, 21 Jan 2018 15:12:32 -0500 Subject: [PATCH] Remove WASM's standard memory operators We've made the decision that sbrk is the way contracts will grow memory. So, remove access to WASM's standardized memory opcodes. As it stood, these subverted our expected memory management. --- libraries/wasm-jit/Include/IR/Operators.h | 7 ++-- .../Source/WASM/WASMSerialization.cpp | 11 ++++++ tests/wasm_tests/test_wasts.hpp | 36 +++++++++++++++++++ tests/wasm_tests/wasm_tests.cpp | 15 ++++++++ 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/libraries/wasm-jit/Include/IR/Operators.h b/libraries/wasm-jit/Include/IR/Operators.h index 100d4e0f2..135fbc4e4 100644 --- a/libraries/wasm-jit/Include/IR/Operators.h +++ b/libraries/wasm-jit/Include/IR/Operators.h @@ -123,6 +123,10 @@ namespace IR ATOMICRMW : (i32,T) -> T */ + #define ENUM_MEMORY_OPERATORS(visitOp) \ + visitOp(0x3f,current_memory,"current_memory",MemoryImm,NULLARY(i32)) \ + visitOp(0x40,grow_memory,"grow_memory",MemoryImm,UNARY(i32,i32)) + #define ENUM_NONCONTROL_NONPARAMETRIC_OPERATORS(visitOp) \ ENUM_NONFLOAT_NONCONTROL_NONPARAMETRIC_OPERATORS(visitOp) \ ENUM_FLOAT_NONCONTROL_NONPARAMETRIC_OPERATORS(visitOp) @@ -130,8 +134,7 @@ namespace IR #define ENUM_NONFLOAT_NONCONTROL_NONPARAMETRIC_OPERATORS(visitOp) \ visitOp(0x01,nop,"nop",NoImm,NULLARY(none)) \ \ - visitOp(0x3f,current_memory,"current_memory",MemoryImm,NULLARY(i32)) \ - visitOp(0x40,grow_memory,"grow_memory",MemoryImm,UNARY(i32,i32)) \ + ENUM_MEMORY_OPERATORS(visitOp) \ \ visitOp(0x28,i32_load,"i32.load",LoadOrStoreImm<2>,LOAD(i32)) \ visitOp(0x29,i64_load,"i64.load",LoadOrStoreImm<3>,LOAD(i64)) \ diff --git a/libraries/wasm-jit/Source/WASM/WASMSerialization.cpp b/libraries/wasm-jit/Source/WASM/WASMSerialization.cpp index cf5feac18..d4195127d 100644 --- a/libraries/wasm-jit/Source/WASM/WASMSerialization.cpp +++ b/libraries/wasm-jit/Source/WASM/WASMSerialization.cpp @@ -613,6 +613,14 @@ namespace WASM { Opcode opcode; serialize(bodyStream,opcode); + + ////disallow memory operations + #define VISIT_OPCODE(_,name,...) \ + if(opcode == Opcode::name) \ + throw FatalSerializationException("memory instructions not allowed"); + ENUM_MEMORY_OPERATORS(VISIT_OPCODE) + #undef VISIT_OPCODE + switch(opcode) { #define VISIT_OPCODE(_,name,nameString,Imm,...) \ @@ -628,11 +636,14 @@ namespace WASM } ENUM_NONFLOAT_OPERATORS(VISIT_OPCODE) #undef VISIT_OPCODE + + /////disallow float operations #define VISIT_OPCODE(_,name,nameString,...) \ case Opcode::name: \ throw FatalSerializationException("float instructions not allowed"); ENUM_FLOAT_NONCONTROL_NONPARAMETRIC_OPERATORS(VISIT_OPCODE) #undef VISIT_OPCODE + default: throw FatalSerializationException("unknown opcode"); }; }; diff --git a/tests/wasm_tests/test_wasts.hpp b/tests/wasm_tests/test_wasts.hpp index f245ba4b2..6477c6e06 100644 --- a/tests/wasm_tests/test_wasts.hpp +++ b/tests/wasm_tests/test_wasts.hpp @@ -79,4 +79,40 @@ static const char mutable_global_wast[] = R"=====( ) (global $g0 (mut i32) (i32.const 2)) ) +)====="; + +static const char current_memory_wast[] = R"=====( +(module + (table 0 anyfunc) + (memory $0 1) + (export "memory" (memory $0)) + (export "init" (func $init)) + (export "apply" (func $apply)) + (func $init + (drop + (current_memory) + ) + ) + (func $apply (param $0 i64) (param $1 i64) + ) +) +)====="; + +static const char grow_memory_wast[] = R"=====( +(module + (table 0 anyfunc) + (memory $0 1) + (export "memory" (memory $0)) + (export "init" (func $init)) + (export "apply" (func $apply)) + (func $init + (drop + (grow_memory + (i32.const 20) + ) + ) + ) + (func $apply (param $0 i64) (param $1 i64) + ) +) )====="; \ No newline at end of file diff --git a/tests/wasm_tests/wasm_tests.cpp b/tests/wasm_tests/wasm_tests.cpp index 8249cdf3b..01ebfb969 100644 --- a/tests/wasm_tests/wasm_tests.cpp +++ b/tests/wasm_tests/wasm_tests.cpp @@ -659,4 +659,19 @@ BOOST_FIXTURE_TEST_CASE( check_global_reset, tester ) try { BOOST_CHECK_EQUAL(transaction_receipt::executed, receipt.status); } FC_LOG_AND_RETHROW() +//Make sure current_memory/grow_memory is not allowed +BOOST_FIXTURE_TEST_CASE( memory_operators, tester ) try { + produce_blocks(2); + + create_accounts( {N(current_memory)}, asset::from_string("1000.0000 EOS") ); + transfer( N(inita), N(current_memory), "10.0000 EOS", "memo" ); + produce_block(); + + BOOST_CHECK_THROW(set_code(N(current_memory), current_memory_wast), fc::unhandled_exception); + produce_blocks(1); + + BOOST_CHECK_THROW(set_code(N(current_memory), grow_memory_wast), fc::unhandled_exception); + +} FC_LOG_AND_RETHROW() + BOOST_AUTO_TEST_SUITE_END() -- GitLab