From 209a1a6ffa5c60128b1a759f090facdfa08e6b91 Mon Sep 17 00:00:00 2001 From: Olek <115580134+oleks-rip@users.noreply.github.com> Date: Thu, 15 Jan 2026 19:52:22 -0500 Subject: [PATCH] Don't throw from hostfunctions stack (#6221) --- src/xrpld/app/wasm/WasmiVM.h | 1 + src/xrpld/app/wasm/detail/HostFuncWrapper.cpp | 9 +++++- src/xrpld/app/wasm/detail/WasmiVM.cpp | 30 ++++++++++++++----- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/xrpld/app/wasm/WasmiVM.h b/src/xrpld/app/wasm/WasmiVM.h index c39b577c46..0d051ea49b 100644 --- a/src/xrpld/app/wasm/WasmiVM.h +++ b/src/xrpld/app/wasm/WasmiVM.h @@ -108,6 +108,7 @@ struct InstanceWrapper { wasm_store_t* store_ = nullptr; WasmExternVec exports_; + mutable int memIdx_ = -1; InstancePtr instance_; beast::Journal j_ = beast::Journal(beast::Journal::getNullSink()); diff --git a/src/xrpld/app/wasm/detail/HostFuncWrapper.cpp b/src/xrpld/app/wasm/detail/HostFuncWrapper.cpp index ee284fa6e9..8910f22aa1 100644 --- a/src/xrpld/app/wasm/detail/HostFuncWrapper.cpp +++ b/src/xrpld/app/wasm/detail/HostFuncWrapper.cpp @@ -332,7 +332,14 @@ checkGas(void* env) int64_t const gas = runtime->getGas(); WasmImportFunc const& impFunc = udata->second; int64_t const x = gas >= impFunc.gas ? gas - impFunc.gas : 0; - runtime->setGas(x); + + if (runtime->setGas(x) < 0) + { + wasm_trap_t* trap = reinterpret_cast( + WasmEngine::instance().newTrap("can't set gas")); // LCOV_EXCL_LINE + return Unexpected(trap); // LCOV_EXCL_LINE + } + if (gas < impFunc.gas) { wasm_trap_t* trap = reinterpret_cast( diff --git a/src/xrpld/app/wasm/detail/WasmiVM.cpp b/src/xrpld/app/wasm/detail/WasmiVM.cpp index 3c56f885dd..8bd4a7b8b8 100644 --- a/src/xrpld/app/wasm/detail/WasmiVM.cpp +++ b/src/xrpld/app/wasm/detail/WasmiVM.cpp @@ -103,6 +103,8 @@ InstanceWrapper::operator=(InstanceWrapper&& o) store_ = o.store_; o.store_ = nullptr; exports_ = std::move(o.exports_); + memIdx_ = o.memIdx_; + o.memIdx_ = -1; instance_ = std::move(o.instance_); j_ = o.j_; @@ -162,22 +164,29 @@ InstanceWrapper::getFunc( wmem InstanceWrapper::getMem() const { - if (!instance_) - throw std::runtime_error("no instance"); // LCOV_EXCL_LINE + if (memIdx_ >= 0) + { + auto* e(exports_.vec_.data[memIdx_]); + wasm_memory_t* mem = wasm_extern_as_memory(e); + return { + reinterpret_cast(wasm_memory_data(mem)), + wasm_memory_data_size(mem)}; + } wasm_memory_t* mem = nullptr; - for (unsigned i = 0; i < exports_.vec_.size; ++i) + for (int i = 0; i < exports_.vec_.size; ++i) { auto* e(exports_.vec_.data[i]); if (wasm_extern_kind(e) == WASM_EXTERN_MEMORY) { + memIdx_ = i; mem = wasm_extern_as_memory(e); break; } } if (!mem) - throw std::runtime_error("no memory exported"); // LCOV_EXCL_LINE + return {}; // LCOV_EXCL_LINE return { reinterpret_cast(wasm_memory_data(mem)), @@ -209,7 +218,7 @@ InstanceWrapper::setGas(std::int64_t gas) const // LCOV_EXCL_START print_wasm_error("Can't set instance gas", nullptr, j_); wasmi_error_delete(err); - throw std::runtime_error("Can't set instance gas"); + return -1; // LCOV_EXCL_STOP } @@ -592,11 +601,13 @@ WasmiEngine::convertParams(std::vector const& params) break; // LCOV_EXCL_STOP case WT_U8V: { + auto mem = getMem(); + if (!mem.s) + throw std::runtime_error( + "no memory exported"); // LCOV_EXCL_LINE auto const sz = p.of.u8v.sz; auto const ptr = allocate(sz); - auto mem = getMem(); memcpy(mem.p + ptr, p.of.u8v.d, sz); - v.push_back(WASM_I32_VAL(ptr)); v.push_back(WASM_I32_VAL(sz)); } @@ -751,8 +762,11 @@ WasmiEngine::call( std::size_t sz, Types&&... args) { - auto const ptr = allocate(sz); auto mem = getMem(); + if (!mem.s) + throw std::runtime_error("no memory exported"); // LCOV_EXCL_LINE + + auto const ptr = allocate(sz); memcpy(mem.p + ptr, d, sz); add_param(in, ptr);