diff --git a/libraries/wasm-jit/Include/IR/Operators.h b/libraries/wasm-jit/Include/IR/Operators.h index 100d4e0f2af231b950db39f3baaf2f55b965acf3..135fbc4e4c01dfa5412e8c47f6cba649a25cd0db 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 cf5feac18f32ef6c43fb795e21e99c567831a5fb..d4195127d263ae7bc954d43639892cee721e78b3 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 f245ba4b2458894d6c3f93fd9d5513532ce68243..6477c6e0680a0e5f06d4e81582acd480673d22f7 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 8249cdf3bb3aa362724c03ee584f80512ab4d8d1..01ebfb969b1d60ba9cb2c1c31c493eb5be2d5b30 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()