From 0d95587bc4fa4eb0fb399fd15deed5439818592c Mon Sep 17 00:00:00 2001 From: Sabaun Taraki Date: Thu, 14 Sep 2023 15:44:07 +0300 Subject: [PATCH 1/5] perf(wasm-gen): Improve fuzzer's and loader's memory testing (#3225) --- utils/node-loader/src/utils.rs | 27 ++++++++++++++++- utils/runtime-fuzzer/README.md | 2 +- utils/runtime-fuzzer/src/arbitrary_call.rs | 30 +++++++++++++++---- utils/wasm-gen/src/config.rs | 20 +++++++++++++ utils/wasm-gen/src/config/generator.rs | 6 ++-- utils/wasm-gen/src/config/syscalls/param.rs | 12 ++++++-- .../src/generator/syscalls/invocator.rs | 22 +++++++++----- utils/wasm-gen/src/tests.rs | 24 ++++++++------- 8 files changed, 112 insertions(+), 31 deletions(-) diff --git a/utils/node-loader/src/utils.rs b/utils/node-loader/src/utils.rs index 9beff5e7cda..883dba6538a 100644 --- a/utils/node-loader/src/utils.rs +++ b/utils/node-loader/src/utils.rs @@ -6,7 +6,10 @@ use gear_call_gen::Seed; use gear_core::ids::{MessageId, ProgramId}; use gear_core_errors::ReplyCode; use gear_utils::NonEmpty; -use gear_wasm_gen::{EntryPointsSet, StandardGearWasmConfigsBundle}; +use gear_wasm_gen::{ + EntryPointsSet, ParamType, StandardGearWasmConfigsBundle, SysCallName, + SysCallsInjectionAmounts, SysCallsParamsConfig, +}; use gsdk::metadata::runtime_types::{ gear_common::event::DispatchStatus as GenDispatchStatus, gear_core::{ @@ -209,10 +212,32 @@ pub fn get_wasm_gen_config( seed: Seed, existing_programs: impl Iterator, ) -> StandardGearWasmConfigsBundle { + let initial_pages = 2; + let mut injection_amounts = SysCallsInjectionAmounts::all_once(); + injection_amounts.set_multiple( + [ + (SysCallName::Leave, 0..=0), + (SysCallName::Panic, 0..=0), + (SysCallName::OomPanic, 0..=0), + (SysCallName::Send, 20..=30), + (SysCallName::Exit, 0..=1), + (SysCallName::Alloc, 5..=10), + (SysCallName::Free, 5..=10), + ] + .into_iter(), + ); + + let mut params_config = SysCallsParamsConfig::default(); + params_config.add_rule(ParamType::Alloc, (1..=10).into()); + params_config.add_rule(ParamType::Free, (initial_pages..=initial_pages + 25).into()); + StandardGearWasmConfigsBundle { log_info: Some(format!("Gear program seed = '{seed}'")), existing_addresses: NonEmpty::collect(existing_programs), entry_points_set: EntryPointsSet::InitHandleHandleReply, + injection_amounts, + params_config, + initial_pages: initial_pages as u32, ..Default::default() } } diff --git a/utils/runtime-fuzzer/README.md b/utils/runtime-fuzzer/README.md index a7600d80bf9..8c141ea4f23 100644 --- a/utils/runtime-fuzzer/README.md +++ b/utils/runtime-fuzzer/README.md @@ -70,7 +70,7 @@ There are two ways to view coverage: ```bash # generate `lcov.info` file with coverage HOST_TARGET=$(rustc -Vv | grep "host: " | sed "s/^host: \(.*\)$/\1/") - cargo cov -- export target/x86_64-unknown-linux-gnu/coverage/x86_64-unknown-linux-gnu/release/main \ + cargo cov -- export target/$HOST_TARGET/coverage/$HOST_TARGET/release/main \ --format=lcov \ --instr-profile=fuzz/coverage/main/coverage.profdata \ --ignore-filename-regex=/rustc/ \ diff --git a/utils/runtime-fuzzer/src/arbitrary_call.rs b/utils/runtime-fuzzer/src/arbitrary_call.rs index e8eb10c5c70..6fed1316c1a 100644 --- a/utils/runtime-fuzzer/src/arbitrary_call.rs +++ b/utils/runtime-fuzzer/src/arbitrary_call.rs @@ -23,7 +23,8 @@ use arbitrary::{Arbitrary, Result, Unstructured}; use gear_core::ids::{CodeId, ProgramId}; use gear_utils::NonEmpty; use gear_wasm_gen::{ - EntryPointsSet, StandardGearWasmConfigsBundle, SysCallName, SysCallsInjectionAmounts, + EntryPointsSet, ParamType, StandardGearWasmConfigsBundle, SysCallName, + SysCallsInjectionAmounts, SysCallsParamsConfig, }; use sha1::*; use std::{ @@ -190,12 +191,27 @@ fn config( programs: [ProgramId; GearCalls::INIT_MSGS], log_info: Option, ) -> StandardGearWasmConfigsBundle { + let initial_pages = 2; let mut injection_amounts = SysCallsInjectionAmounts::all_once(); - injection_amounts.set(SysCallName::Leave, 0, 0); - injection_amounts.set(SysCallName::Panic, 0, 0); - injection_amounts.set(SysCallName::OomPanic, 0, 0); - injection_amounts.set(SysCallName::Send, 20, 30); - injection_amounts.set(SysCallName::Exit, 0, 1); + injection_amounts.set_multiple( + [ + (SysCallName::Leave, 0..=0), + (SysCallName::Panic, 0..=0), + (SysCallName::OomPanic, 0..=0), + (SysCallName::Send, 20..=30), + (SysCallName::Exit, 0..=1), + (SysCallName::Alloc, 20..=30), + (SysCallName::Free, 20..=30), + ] + .into_iter(), + ); + + let mut params_config = SysCallsParamsConfig::default(); + params_config.add_rule(ParamType::Alloc, (10..=20).into()); + params_config.add_rule( + ParamType::Free, + (initial_pages..=initial_pages + 250).into(), + ); let existing_addresses = NonEmpty::collect( programs @@ -214,6 +230,8 @@ fn config( injection_amounts, existing_addresses, log_info, + params_config, + initial_pages: initial_pages as u32, ..Default::default() } } diff --git a/utils/wasm-gen/src/config.rs b/utils/wasm-gen/src/config.rs index e07b62de0e7..5993ab0283e 100644 --- a/utils/wasm-gen/src/config.rs +++ b/utils/wasm-gen/src/config.rs @@ -147,6 +147,12 @@ pub struct StandardGearWasmConfigsBundle { pub injection_amounts: SysCallsInjectionAmounts, /// Config of gear wasm call entry-points (exports). pub entry_points_set: EntryPointsSet, + /// Initial wasm memory pages. + pub initial_pages: u32, + /// Optional stack end pages. + pub stack_end_page: Option, + /// Sys-calls params config + pub params_config: SysCallsParamsConfig, } impl Default for StandardGearWasmConfigsBundle { @@ -158,6 +164,9 @@ impl Default for StandardGearWasmConfigsBundle { call_indirect_enabled: true, injection_amounts: SysCallsInjectionAmounts::all_once(), entry_points_set: Default::default(), + initial_pages: DEFAULT_INITIAL_SIZE, + stack_end_page: None, + params_config: SysCallsParamsConfig::default(), } } } @@ -171,6 +180,9 @@ impl> ConfigsBundle for StandardGearWasmConfigsBundle { call_indirect_enabled, injection_amounts, entry_points_set, + initial_pages, + stack_end_page, + params_config, } = self; let selectable_params = SelectableParams { @@ -188,10 +200,18 @@ impl> ConfigsBundle for StandardGearWasmConfigsBundle { } else { sys_calls_config_builder = sys_calls_config_builder.with_source_msg_dest(); } + sys_calls_config_builder = sys_calls_config_builder.with_params_config(params_config); + + let memory_pages_config = MemoryPagesConfig { + initial_size: initial_pages, + stack_end_page, + upper_limit: None, + }; let gear_wasm_generator_config = GearWasmGeneratorConfigBuilder::new() .with_recursions_removed(remove_recursion) .with_sys_calls_config(sys_calls_config_builder.build()) .with_entry_points_config(entry_points_set) + .with_memory_config(memory_pages_config) .build(); (gear_wasm_generator_config, selectable_params) diff --git a/utils/wasm-gen/src/config/generator.rs b/utils/wasm-gen/src/config/generator.rs index 5ee9341d8bd..7d831396143 100644 --- a/utils/wasm-gen/src/config/generator.rs +++ b/utils/wasm-gen/src/config/generator.rs @@ -20,6 +20,8 @@ use crate::SysCallsConfig; +pub(crate) const DEFAULT_INITIAL_SIZE: u32 = 16; + /// Builder for [`GearWasmGeneratorConfig`]. pub struct GearWasmGeneratorConfigBuilder(GearWasmGeneratorConfig); @@ -95,9 +97,9 @@ pub struct MemoryPagesConfig { impl Default for MemoryPagesConfig { fn default() -> Self { Self { - initial_size: Self::MAX_VALUE / 2 + 5, + initial_size: DEFAULT_INITIAL_SIZE, upper_limit: None, - stack_end_page: Some(Self::MAX_VALUE / 2), + stack_end_page: None, } } } diff --git a/utils/wasm-gen/src/config/syscalls/param.rs b/utils/wasm-gen/src/config/syscalls/param.rs index 81b94c3e90b..705bdd580ed 100644 --- a/utils/wasm-gen/src/config/syscalls/param.rs +++ b/utils/wasm-gen/src/config/syscalls/param.rs @@ -20,10 +20,12 @@ //! //! Types here are used to create [`crate::SysCallsConfig`]. +use crate::DEFAULT_INITIAL_SIZE; use arbitrary::{Result, Unstructured}; -use gear_wasm_instrument::syscalls::ParamType; use std::{collections::HashMap, ops::RangeInclusive}; +pub use gear_wasm_instrument::syscalls::ParamType; + /// Sys-calls params config. /// /// This is basically a map, which creates a relationship between each kind of @@ -42,6 +44,10 @@ use std::{collections::HashMap, ops::RangeInclusive}; pub struct SysCallsParamsConfig(HashMap); impl SysCallsParamsConfig { + pub fn empty() -> Self { + Self(HashMap::new()) + } + /// New [`SysCallsParamsConfig`] with all rules set to produce one constant value. pub fn all_constant_value(value: i64) -> Self { let allowed_values: SysCallParamAllowedValues = (value..=value).into(); @@ -77,6 +83,8 @@ impl SysCallsParamsConfig { impl Default for SysCallsParamsConfig { fn default() -> Self { + let free_start = DEFAULT_INITIAL_SIZE as i64; + let free_end = free_start + 5; Self( [ (ParamType::Size, (0..=0x10000).into()), @@ -87,7 +95,7 @@ impl Default for SysCallsParamsConfig { (ParamType::Duration, (1..=8).into()), (ParamType::Delay, (0..=4).into()), (ParamType::Handler, (0..=100).into()), - (ParamType::Free, (0..=512).into()), + (ParamType::Free, (free_start..=free_end).into()), ] .into_iter() .collect(), diff --git a/utils/wasm-gen/src/generator/syscalls/invocator.rs b/utils/wasm-gen/src/generator/syscalls/invocator.rs index 479913e10cf..412408dddbb 100644 --- a/utils/wasm-gen/src/generator/syscalls/invocator.rs +++ b/utils/wasm-gen/src/generator/syscalls/invocator.rs @@ -35,7 +35,9 @@ use std::{collections::BTreeMap, iter}; #[derive(Debug)] pub(crate) enum ProcessedSysCallParams { - Alloc, + Alloc { + allowed_values: Option, + }, Value { value_type: ValueType, allowed_values: Option, @@ -56,7 +58,9 @@ pub(crate) fn process_sys_call_params( continue; } let processed_param = match param { - ParamType::Alloc => ProcessedSysCallParams::Alloc, + ParamType::Alloc => ProcessedSysCallParams::Alloc { + allowed_values: params_config.get_rule(¶m), + }, ParamType::Ptr(maybe_idx) => maybe_idx .map(|_| { // skipping next as we don't need the following `Size` param, @@ -360,15 +364,17 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { let mut setters = Vec::with_capacity(params.len()); for processed_param in process_sys_call_params(params, self.config.params_config()) { match processed_param { - ProcessedSysCallParams::Alloc => { - let pages_to_alloc = self - .unstructured - .int_in_range(0..=mem_size_pages.saturating_sub(1))?; - let setter = ParamSetter::new_i32(pages_to_alloc as i32); + ProcessedSysCallParams::Alloc { allowed_values } => { + let pages_to_alloc = if let Some(allowed_values) = allowed_values { + allowed_values.get_i32(self.unstructured)? + } else { + let mem_size_pages = (mem_size_pages / 3).max(1); + self.unstructured.int_in_range(0..=mem_size_pages)? as i32 + }; log::trace!(" ---- Allocate memory - {pages_to_alloc}"); - setters.push(setter); + setters.push(ParamSetter::new_i32(pages_to_alloc)); } ProcessedSysCallParams::Value { value_type, diff --git a/utils/wasm-gen/src/tests.rs b/utils/wasm-gen/src/tests.rs index 1f45db0b6fd..78830b304e8 100644 --- a/utils/wasm-gen/src/tests.rs +++ b/utils/wasm-gen/src/tests.rs @@ -18,17 +18,25 @@ use super::*; use arbitrary::Unstructured; -use gear_backend_common::{TerminationReason, TrapExplanation}; +use gear_backend_common::{BackendReport, Environment, TerminationReason, TrapExplanation}; +use gear_backend_sandbox::SandboxEnvironment; use gear_core::{ code::Code, memory::Memory, - message::{IncomingMessage, ReplyPacket}, + message::{ + ContextSettings, DispatchKind, IncomingDispatch, IncomingMessage, MessageContext, + ReplyPacket, + }, pages::WASM_PAGE_SIZE, }; +use gear_core_processor::{ProcessorContext, ProcessorExternalities}; use gear_utils::NonEmpty; -use gear_wasm_instrument::parity_wasm::{ - self, - elements::{Instruction, Module}, +use gear_wasm_instrument::{ + parity_wasm::{ + self, + elements::{Instruction, Module}, + }, + rules::CustomConstantCostRules, }; use proptest::prelude::*; use rand::{rngs::SmallRng, RngCore, SeedableRng}; @@ -231,12 +239,6 @@ fn execute_wasm_with_syscall_injected( params_config: SysCallsParamsConfig, initial_memory_write: Option, ) -> TerminationReason { - use gear_backend_common::{BackendReport, Environment}; - use gear_backend_sandbox::SandboxEnvironment; - use gear_core::message::{ContextSettings, DispatchKind, IncomingDispatch, MessageContext}; - use gear_core_processor::{ProcessorContext, ProcessorExternalities}; - use gear_wasm_instrument::rules::CustomConstantCostRules; - const INITIAL_PAGES: u16 = 1; const INJECTED_SYSCALLS: u32 = 8; From ebd6a7c0ba26b6170f2d05268e7a01c17b4517f7 Mon Sep 17 00:00:00 2001 From: StackOverflowExcept1on <109800286+StackOverflowExcept1on@users.noreply.github.com> Date: Thu, 14 Sep 2023 15:48:38 +0300 Subject: [PATCH 2/5] feat(wasm-gen): make first param of `gr_exit` configurable (#3237) --- utils/wasm-gen/src/config/syscalls.rs | 42 ++++----- .../src/generator/syscalls/additional_data.rs | 4 +- .../src/generator/syscalls/invocator.rs | 92 ++++++++++--------- 3 files changed, 74 insertions(+), 64 deletions(-) diff --git a/utils/wasm-gen/src/config/syscalls.rs b/utils/wasm-gen/src/config/syscalls.rs index b9a37a4ed17..fb6e3870bf6 100644 --- a/utils/wasm-gen/src/config/syscalls.rs +++ b/utils/wasm-gen/src/config/syscalls.rs @@ -41,7 +41,7 @@ impl SysCallsConfigBuilder { Self(SysCallsConfig { injection_amounts, params_config: SysCallsParamsConfig::default(), - sending_message_destination: MessageDestination::default(), + sys_call_destination: SysCallDestination::default(), error_processing_config: ErrorProcessingConfig::None, log_info: None, }) @@ -54,23 +54,23 @@ impl SysCallsConfigBuilder { self } - /// Set whether `gr_send*` sys-calls must use `gr_source` result for message destination. + /// Set whether `gr_send*` and `gr_exit` sys-calls must use `gr_source` result for sys-call destination. pub fn with_source_msg_dest(mut self) -> Self { - self.0.sending_message_destination = MessageDestination::Source; + self.0.sys_call_destination = SysCallDestination::Source; self.enable_sys_call(SysCallName::Source); self } - /// Set whether `gr_send*` sys-calls must use some address from `addresses` collection - /// as a message destination. + /// Set whether `gr_send*` and `gr_exit` sys-calls must use some address from `addresses` collection + /// as a sys-call destination. pub fn with_data_offset_msg_dest>(mut self, addresses: NonEmpty) -> Self { let addresses = NonEmpty::collect(addresses.into_iter().map(|pid| HashWithValue { hash: pid.into(), value: 0, })) .expect("collected from non empty"); - self.0.sending_message_destination = MessageDestination::ExistingAddresses(addresses); + self.0.sys_call_destination = SysCallDestination::ExistingAddresses(addresses); self } @@ -138,7 +138,7 @@ impl ErrorProcessingConfig { pub struct SysCallsConfig { injection_amounts: SysCallsInjectionAmounts, params_config: SysCallsParamsConfig, - sending_message_destination: MessageDestination, + sys_call_destination: SysCallDestination, error_processing_config: ErrorProcessingConfig, log_info: Option, } @@ -149,11 +149,11 @@ impl SysCallsConfig { self.injection_amounts.get(name) } - /// Get defined message destination for `gr_send*` sys-calls. + /// Get defined sys-call destination for `gr_send*` and `gr_exit` sys-calls. /// - /// For more info, read [`MessageDestination`]. - pub fn sending_message_destination(&self) -> &MessageDestination { - &self.sending_message_destination + /// For more info, read [`SysCallDestination`]. + pub fn sys_call_destination(&self) -> &SysCallDestination { + &self.sys_call_destination } /// Get defined log info. @@ -174,33 +174,33 @@ impl SysCallsConfig { } } -/// Message destination choice. +/// Sys-call destination choice. /// -/// `gr_send*` sys-calls generated from this crate can send messages +/// `gr_send*` and `gr_exit` sys-calls generated from this crate can be sent /// to different destination in accordance to the config. /// It's either to the message source, to some existing known address, /// or to some random, most probably non-existing, address. #[derive(Debug, Clone, Default)] -pub enum MessageDestination { +pub enum SysCallDestination { Source, ExistingAddresses(NonEmpty), #[default] Random, } -impl MessageDestination { - /// Check whether message destination is a result of `gr_source`. +impl SysCallDestination { + /// Check whether sys-call destination is a result of `gr_source`. pub fn is_source(&self) -> bool { - matches!(&self, MessageDestination::Source) + matches!(&self, SysCallDestination::Source) } - /// Check whether message destination is defined randomly. + /// Check whether sys-call destination is defined randomly. pub fn is_random(&self) -> bool { - matches!(&self, MessageDestination::Random) + matches!(&self, SysCallDestination::Random) } - /// Check whether message destination is defined from a collection of existing addresses. + /// Check whether sys-call destination is defined from a collection of existing addresses. pub fn is_existing_addresses(&self) -> bool { - matches!(&self, MessageDestination::ExistingAddresses(_)) + matches!(&self, SysCallDestination::ExistingAddresses(_)) } } diff --git a/utils/wasm-gen/src/generator/syscalls/additional_data.rs b/utils/wasm-gen/src/generator/syscalls/additional_data.rs index 4a2cdbb3751..ed31137c446 100644 --- a/utils/wasm-gen/src/generator/syscalls/additional_data.rs +++ b/utils/wasm-gen/src/generator/syscalls/additional_data.rs @@ -23,7 +23,7 @@ use crate::{ CallIndexes, CallIndexesHandle, DisabledSysCallsImportsGenerator, ModuleWithCallIndexes, SysCallsImportsGenerationProof, }, - utils, EntryPointName, InvocableSysCall, MessageDestination, SysCallsConfig, WasmModule, + utils, EntryPointName, InvocableSysCall, SysCallDestination, SysCallsConfig, WasmModule, }; use arbitrary::Unstructured; use gear_core::ids::ProgramId; @@ -140,7 +140,7 @@ impl<'a, 'b> AdditionalDataInjector<'a, 'b> { )); } - let MessageDestination::ExistingAddresses(existing_addresses) = self.config.sending_message_destination() else { + let SysCallDestination::ExistingAddresses(existing_addresses) = self.config.sys_call_destination() else { return None; }; diff --git a/utils/wasm-gen/src/generator/syscalls/invocator.rs b/utils/wasm-gen/src/generator/syscalls/invocator.rs index 412408dddbb..df5d3fca451 100644 --- a/utils/wasm-gen/src/generator/syscalls/invocator.rs +++ b/utils/wasm-gen/src/generator/syscalls/invocator.rs @@ -91,7 +91,7 @@ pub(crate) fn process_sys_call_params( /// data injection outcome ([`AddressesInjectionOutcome`]). The latter was introduced /// to give additional guarantees for config and generators consistency. Otherwise, /// if there wasn't any addresses injection outcome, which signals that there was a try to -/// inject addresses, sys-calls invocator could falsely set `gr_send*` call's destination param +/// inject addresses, sys-calls invocator could falsely set `gr_send*` and `gr_exit` call's destination param /// to random value. For example, existing addresses could have been defined in the config, but /// additional data injector was disabled, before injecting addresses from the config. As a result, /// invocator would set un-intended by config values as messages destination. To avoid such @@ -174,8 +174,11 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { ); for (invocable, (amount, call_indexes_handle)) in self.sys_call_imports.clone() { - let instructions = - self.build_sys_call_invoke_instructions(invocable, call_indexes_handle)?; + let instructions = self.build_sys_call_invoke_instructions( + invocable, + invocable.into_signature(), + call_indexes_handle, + )?; log::trace!( "Inserting the {} sys_call {} times", @@ -204,6 +207,7 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { fn build_sys_call_invoke_instructions( &mut self, invocable: InvocableSysCall, + signature: SysCallSignature, call_indexes_handle: CallIndexesHandle, ) -> Result> { log::trace!( @@ -212,42 +216,37 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { self.unstructured.len() ); - let insert_error_processing = self - .config - .error_processing_config() - .error_should_be_processed(&invocable); - let (fallible, mut signature) = (invocable.is_fallible(), invocable.into_signature()); - - if self.is_not_send_sys_call(invocable) { + if self.is_sys_call_with_destination(invocable) { log::trace!( - " -- Generating build call for non-send sys-call {}", + " -- Generating build call for {} sys-call with destination", invocable.to_str() ); - return self.build_call( - signature, - fallible, - insert_error_processing, - call_indexes_handle, + + self.build_call_with_destination(invocable, signature, call_indexes_handle) + } else { + log::trace!( + " -- Generating build call for common sys-call {}", + invocable.to_str() ); - } - log::trace!( - " -- Generating build call for send sys-call {}", - invocable.to_str() - ); + self.build_call(invocable, signature, call_indexes_handle) + } + } + fn build_call_with_destination( + &mut self, + invocable: InvocableSysCall, + mut signature: SysCallSignature, + call_indexes_handle: CallIndexesHandle, + ) -> Result> { // The value for the first param is chosen from config. // It's either the result of `gr_source`, some existing address (set in the data section) or a completely random value. signature.params.remove(0); - let mut call_without_destination_instrs = self.build_call( - signature, - fallible, - insert_error_processing, - call_indexes_handle, - )?; + let mut call_without_destination_instrs = + self.build_call(invocable, signature, call_indexes_handle)?; - let res = if self.config.sending_message_destination().is_source() { - log::trace!(" -- Message destination is result of `gr_source`"); + let res = if self.config.sys_call_destination().is_source() { + log::trace!(" -- Sys-call destination is result of `gr_source`"); let gr_source_call_indexes_handle = self .sys_call_imports @@ -282,17 +281,14 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { let address_offset = match self.offsets.as_mut() { Some(offsets) => { - assert!(self - .config - .sending_message_destination() - .is_existing_addresses()); - log::trace!(" -- Message destination is an existing program address"); + assert!(self.config.sys_call_destination().is_existing_addresses()); + log::trace!(" -- Sys-call destination is an existing program address"); offsets.next_offset() } None => { - assert!(self.config.sending_message_destination().is_random()); - log::trace!(" -- Message destination is a random address"); + assert!(self.config.sys_call_destination().is_random()); + log::trace!(" -- Sys-call destination is a random address"); self.unstructured.arbitrary()? } @@ -307,23 +303,32 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { Ok(res) } - fn is_not_send_sys_call(&self, sys_call: InvocableSysCall) -> bool { + fn is_sys_call_with_destination(&self, sys_call: InvocableSysCall) -> bool { + self.is_send_sys_call(sys_call) || self.is_exit_sys_call(sys_call) + } + + fn is_send_sys_call(&self, sys_call: InvocableSysCall) -> bool { use InvocableSysCall::*; - ![ + [ Loose(SysCallName::Send), Loose(SysCallName::SendWGas), Loose(SysCallName::SendInput), Loose(SysCallName::SendInputWGas), Precise(SysCallName::ReservationSend), + Precise(SysCallName::SendCommit), + Precise(SysCallName::SendCommitWGas), ] .contains(&sys_call) } + fn is_exit_sys_call(&self, sys_call: InvocableSysCall) -> bool { + matches!(sys_call, InvocableSysCall::Loose(SysCallName::Exit)) + } + fn build_call( &mut self, + invocable: InvocableSysCall, signature: SysCallSignature, - fallible: bool, - insert_error_processing: bool, call_indexes_handle: CallIndexesHandle, ) -> Result> { let param_setters = self.build_param_setters(&signature.params)?; @@ -335,9 +340,14 @@ impl<'a, 'b> SysCallsInvocator<'a, 'b> { instructions.push(Instruction::Call(call_indexes_handle as u32)); + let insert_error_processing = self + .config + .error_processing_config() + .error_should_be_processed(&invocable); + let mut result_processing = if !insert_error_processing { Self::build_result_processing_ignored(signature) - } else if fallible { + } else if invocable.is_fallible() { Self::build_result_processing_fallible(signature, ¶m_setters) } else { Self::build_result_processing_infallible(signature) From 2a8903a1d716aaa7bee3b07adc3b034d937b2ebe Mon Sep 17 00:00:00 2001 From: Dmitriy <128726599+Magorsky@users.noreply.github.com> Date: Thu, 14 Sep 2023 15:50:29 +0300 Subject: [PATCH 3/5] update base image for dockerfile fuzzer (#3267) Co-authored-by: magorsky --- docker/runtime-fuzzer/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/runtime-fuzzer/Dockerfile b/docker/runtime-fuzzer/Dockerfile index 339055cb3b4..9cf7f8550f4 100644 --- a/docker/runtime-fuzzer/Dockerfile +++ b/docker/runtime-fuzzer/Dockerfile @@ -1,4 +1,4 @@ -FROM ubuntu:22.10 +FROM ubuntu:22.04 MAINTAINER GEAR From bb7864cfa7f9dbeee495b4ec611e20c60e8abf83 Mon Sep 17 00:00:00 2001 From: Sabaun Taraki Date: Thu, 14 Sep 2023 16:53:34 +0300 Subject: [PATCH 4/5] feat(runtime-fuzzer): Introduce `run_corpus` script (#3260) --- utils/runtime-fuzzer/Cargo.toml | 4 ++ utils/runtime-fuzzer/bin/run_corpus.rs | 58 ++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 utils/runtime-fuzzer/bin/run_corpus.rs diff --git a/utils/runtime-fuzzer/Cargo.toml b/utils/runtime-fuzzer/Cargo.toml index 0c145193e63..410ab54b0f9 100644 --- a/utils/runtime-fuzzer/Cargo.toml +++ b/utils/runtime-fuzzer/Cargo.toml @@ -4,6 +4,10 @@ version = "0.1.0" authors.workspace = true edition.workspace = true +[[bin]] +name = "run_corpus" +path = "bin/run_corpus.rs" + [dependencies] anyhow.workspace = true arbitrary.workspace = true diff --git a/utils/runtime-fuzzer/bin/run_corpus.rs b/utils/runtime-fuzzer/bin/run_corpus.rs new file mode 100644 index 00000000000..fd4e2aaa66b --- /dev/null +++ b/utils/runtime-fuzzer/bin/run_corpus.rs @@ -0,0 +1,58 @@ +// This file is part of Gear. + +// Copyright (C) 2021-2023 Gear Technologies Inc. +// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0 + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +//! Runs provided from the cli corpus +//! +//! Alternatively, `cargo fuzz run` can be used to reproduce some corpus, +//! but it won't give logs of [`GearCalls`] generation, which sheds some +//! light on how `gear-wasm-gen` worked. +//! +//! Also that script can be used to run any bytes input, not only fuzzer's +//! corpus. +//! +//! Just simply run `cargo run --release -- -p `. + +use anyhow::Result; +use arbitrary::{Arbitrary, Unstructured}; +use clap::Parser; +use runtime_fuzzer::{self, GearCalls}; +use std::{fs, path::PathBuf}; + +/// A simple tool to run corpus. +#[derive(Debug, Parser)] +#[command(author, version, about, long_about = None)] +struct Params { + /// Path to the file, which contains corpus. + #[arg(short, long)] + path: PathBuf, +} + +fn main() -> Result<()> { + let params = Params::parse(); + + let corpus_bytes = fs::read(params.path)?; + + gear_utils::init_default_logger(); + + let mut unstructured = Unstructured::new(&corpus_bytes); + let gear_calls = GearCalls::arbitrary(&mut unstructured)?; + + runtime_fuzzer::run(gear_calls); + + Ok(()) +} From 73d7d8298f971a549d0df18cf878b3dff5b0ba51 Mon Sep 17 00:00:00 2001 From: StackOverflowExcept1on <109800286+StackOverflowExcept1on@users.noreply.github.com> Date: Mon, 18 Sep 2023 14:32:07 +0300 Subject: [PATCH 5/5] feat(wasm-gen): create config for precise sys-calls (#3262) --- utils/node-loader/src/utils.rs | 3 +- utils/runtime-fuzzer/src/arbitrary_call.rs | 3 +- utils/wasm-gen/src/config/syscalls.rs | 8 +- utils/wasm-gen/src/config/syscalls/amount.rs | 34 +++-- utils/wasm-gen/src/generator/syscalls.rs | 38 +++++ .../src/generator/syscalls/imports.rs | 132 ++++++++---------- utils/wasm-gen/src/tests.rs | 6 +- 7 files changed, 134 insertions(+), 90 deletions(-) diff --git a/utils/node-loader/src/utils.rs b/utils/node-loader/src/utils.rs index 883dba6538a..d63d12ea75a 100644 --- a/utils/node-loader/src/utils.rs +++ b/utils/node-loader/src/utils.rs @@ -7,7 +7,7 @@ use gear_core::ids::{MessageId, ProgramId}; use gear_core_errors::ReplyCode; use gear_utils::NonEmpty; use gear_wasm_gen::{ - EntryPointsSet, ParamType, StandardGearWasmConfigsBundle, SysCallName, + EntryPointsSet, InvocableSysCall, ParamType, StandardGearWasmConfigsBundle, SysCallName, SysCallsInjectionAmounts, SysCallsParamsConfig, }; use gsdk::metadata::runtime_types::{ @@ -224,6 +224,7 @@ pub fn get_wasm_gen_config( (SysCallName::Alloc, 5..=10), (SysCallName::Free, 5..=10), ] + .map(|(sys_call, range)| (InvocableSysCall::Loose(sys_call), range)) .into_iter(), ); diff --git a/utils/runtime-fuzzer/src/arbitrary_call.rs b/utils/runtime-fuzzer/src/arbitrary_call.rs index 6fed1316c1a..5f4d9f5836f 100644 --- a/utils/runtime-fuzzer/src/arbitrary_call.rs +++ b/utils/runtime-fuzzer/src/arbitrary_call.rs @@ -23,7 +23,7 @@ use arbitrary::{Arbitrary, Result, Unstructured}; use gear_core::ids::{CodeId, ProgramId}; use gear_utils::NonEmpty; use gear_wasm_gen::{ - EntryPointsSet, ParamType, StandardGearWasmConfigsBundle, SysCallName, + EntryPointsSet, InvocableSysCall, ParamType, StandardGearWasmConfigsBundle, SysCallName, SysCallsInjectionAmounts, SysCallsParamsConfig, }; use sha1::*; @@ -203,6 +203,7 @@ fn config( (SysCallName::Alloc, 20..=30), (SysCallName::Free, 20..=30), ] + .map(|(sys_call, range)| (InvocableSysCall::Loose(sys_call), range)) .into_iter(), ); diff --git a/utils/wasm-gen/src/config/syscalls.rs b/utils/wasm-gen/src/config/syscalls.rs index fb6e3870bf6..baa69462473 100644 --- a/utils/wasm-gen/src/config/syscalls.rs +++ b/utils/wasm-gen/src/config/syscalls.rs @@ -57,7 +57,7 @@ impl SysCallsConfigBuilder { /// Set whether `gr_send*` and `gr_exit` sys-calls must use `gr_source` result for sys-call destination. pub fn with_source_msg_dest(mut self) -> Self { self.0.sys_call_destination = SysCallDestination::Source; - self.enable_sys_call(SysCallName::Source); + self.enable_sys_call(InvocableSysCall::Loose(SysCallName::Source)); self } @@ -81,7 +81,7 @@ impl SysCallsConfigBuilder { /// Choosing gear export to log data is done from best `init` to worse `handle`. pub fn with_log_info(mut self, log: String) -> Self { self.0.log_info = Some(log); - self.enable_sys_call(SysCallName::Debug); + self.enable_sys_call(InvocableSysCall::Loose(SysCallName::Debug)); self } @@ -93,7 +93,7 @@ impl SysCallsConfigBuilder { self } - fn enable_sys_call(&mut self, name: SysCallName) { + fn enable_sys_call(&mut self, name: InvocableSysCall) { let range = self.0.injection_amounts.get(name); let range_start = *range.start(); @@ -145,7 +145,7 @@ pub struct SysCallsConfig { impl SysCallsConfig { /// Get possible number of times (range) the sys-call can be injected in the wasm. - pub fn injection_amounts(&self, name: SysCallName) -> RangeInclusive { + pub fn injection_amounts(&self, name: InvocableSysCall) -> RangeInclusive { self.injection_amounts.get(name) } diff --git a/utils/wasm-gen/src/config/syscalls/amount.rs b/utils/wasm-gen/src/config/syscalls/amount.rs index 10653a8ab74..58350dea518 100644 --- a/utils/wasm-gen/src/config/syscalls/amount.rs +++ b/utils/wasm-gen/src/config/syscalls/amount.rs @@ -20,36 +20,44 @@ //! //! Types here are used to create [`crate::SysCallsConfig`]. +use crate::InvocableSysCall; + use gear_wasm_instrument::syscalls::SysCallName; use std::{collections::HashMap, ops::RangeInclusive}; /// Possible injection amount ranges for each sys-call. #[derive(Debug, Clone)] -pub struct SysCallsInjectionAmounts(HashMap>); +pub struct SysCallsInjectionAmounts(HashMap>); impl SysCallsInjectionAmounts { /// Instantiate a sys-calls amounts ranges map, where each gear sys-call is injected into wasm-module only once. pub fn all_once() -> Self { - Self( - SysCallName::instrumentable() - .into_iter() - .map(|name| (name, (1..=1))) - .collect(), - ) + Self::new_with_range(1..=1) } /// Instantiate a sys-calls amounts ranges map, where no gear sys-call is ever injected into wasm-module. pub fn all_never() -> Self { + Self::new_with_range(0..=0) + } + + /// Instantiate a sys-calls amounts ranges map with given range. + fn new_with_range(range: RangeInclusive) -> Self { + let sys_calls = SysCallName::instrumentable(); Self( - SysCallName::instrumentable() - .into_iter() - .map(|name| (name, (0..=0))) + sys_calls + .iter() + .cloned() + .map(|name| (InvocableSysCall::Loose(name), range.clone())) + .chain(sys_calls.iter().cloned().filter_map(|name| { + InvocableSysCall::has_precise_variant(name) + .then_some((InvocableSysCall::Precise(name), range.clone())) + })) .collect(), ) } /// Get amount possible sys-call amount range. - pub fn get(&self, name: SysCallName) -> RangeInclusive { + pub fn get(&self, name: InvocableSysCall) -> RangeInclusive { self.0 .get(&name) .cloned() @@ -57,14 +65,14 @@ impl SysCallsInjectionAmounts { } /// Sets possible amount range for the the sys-call. - pub fn set(&mut self, name: SysCallName, min: u32, max: u32) { + pub fn set(&mut self, name: InvocableSysCall, min: u32, max: u32) { self.0.insert(name, min..=max); } /// Same as [`SysCallsAmountRanges::set`], but sets amount ranges for multiple sys-calls. pub fn set_multiple( &mut self, - sys_calls_freqs: impl Iterator)>, + sys_calls_freqs: impl Iterator)>, ) { self.0.extend(sys_calls_freqs) } diff --git a/utils/wasm-gen/src/generator/syscalls.rs b/utils/wasm-gen/src/generator/syscalls.rs index 5b667c216fe..20997838ed6 100644 --- a/utils/wasm-gen/src/generator/syscalls.rs +++ b/utils/wasm-gen/src/generator/syscalls.rs @@ -113,6 +113,44 @@ impl InvocableSysCall { } } + /// Checks whether given sys-call has the precise variant. + pub(crate) fn has_precise_variant(sys_call: SysCallName) -> bool { + Self::required_imports_for_sys_call(sys_call).is_some() + } + + /// Returns the required imports to build precise sys-call. + fn required_imports_for_sys_call(sys_call: SysCallName) -> Option<&'static [SysCallName]> { + // NOTE: the last sys-call must be pattern itself + Some(match sys_call { + SysCallName::ReservationSend => { + &[SysCallName::ReserveGas, SysCallName::ReservationSend] + } + SysCallName::ReservationReply => { + &[SysCallName::ReserveGas, SysCallName::ReservationReply] + } + SysCallName::SendCommit => &[ + SysCallName::SendInit, + SysCallName::SendPush, + SysCallName::SendCommit, + ], + SysCallName::SendCommitWGas => &[ + SysCallName::Size, + SysCallName::SendInit, + SysCallName::SendPushInput, + SysCallName::SendCommitWGas, + ], + _ => return None, + }) + } + + /// Returns the required imports to build precise sys-call, but of a fixed size. + fn required_imports(sys_call: SysCallName) -> &'static [SysCallName; N] { + Self::required_imports_for_sys_call(sys_call) + .expect("failed to find required imports for sys-call") + .try_into() + .expect("failed to convert slice") + } + // If syscall changes from fallible into infallible or vice versa in future, // we'll see it by analyzing code coverage stats produced by fuzzer. pub(crate) fn is_fallible(&self) -> bool { diff --git a/utils/wasm-gen/src/generator/syscalls/imports.rs b/utils/wasm-gen/src/generator/syscalls/imports.rs index 8389f943f08..91887407814 100644 --- a/utils/wasm-gen/src/generator/syscalls/imports.rs +++ b/utils/wasm-gen/src/generator/syscalls/imports.rs @@ -57,16 +57,9 @@ pub struct SysCallsImportsGeneratorInstantiator<'a, 'b>( ), ); -/// The set of sys-calls that need to be imported to create precise sys-call. -#[derive(thiserror::Error, Debug)] -#[error("The following sys-calls must be imported: {0:?}")] -pub struct RequiredSysCalls(&'static [SysCallName]); - /// An error that occurs when generating precise sys-call. #[derive(thiserror::Error, Debug)] pub enum PreciseSysCallError { - #[error("{0}")] - RequiredImports(#[from] RequiredSysCalls), #[error("{0}")] Arbitrary(#[from] ArbitraryError), } @@ -197,16 +190,32 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { /// Generates precise sys-calls and handles errors if any occurred during generation. fn generate_precise_sys_calls(&mut self) -> Result<()> { - for result in [ - self.generate_send_from_reservation(), - self.generate_reply_from_reservation(), - self.generate_send_commit(), - self.generate_send_commit_with_gas(), - ] { - if let Err(err) = result { - match err { - PreciseSysCallError::RequiredImports(err) => log::trace!("{err}"), - PreciseSysCallError::Arbitrary(err) => return Err(err), + use SysCallName::*; + + #[allow(clippy::type_complexity)] + let sys_calls: [( + SysCallName, + fn(&mut Self, SysCallName) -> Result<(), PreciseSysCallError>, + ); 4] = [ + (ReservationSend, Self::generate_send_from_reservation), + (ReservationReply, Self::generate_reply_from_reservation), + (SendCommit, Self::generate_send_commit), + (SendCommitWGas, Self::generate_send_commit_with_gas), + ]; + + for (sys_call, generate_method) in sys_calls { + let sys_call_amount_range = self + .config + .injection_amounts(InvocableSysCall::Precise(sys_call)); + let sys_call_amount = self.unstructured.int_in_range(sys_call_amount_range)?; + for _ in 0..sys_call_amount { + log::trace!( + "Constructing {name} sys-call...", + name = InvocableSysCall::Precise(sys_call).to_str() + ); + + if let Err(PreciseSysCallError::Arbitrary(err)) = generate_method(self, sys_call) { + return Err(err); } } } @@ -223,7 +232,9 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { &mut self, sys_call: SysCallName, ) -> Result> { - let sys_call_amount_range = self.config.injection_amounts(sys_call); + let sys_call_amount_range = self + .config + .injection_amounts(InvocableSysCall::Loose(sys_call)); let sys_call_amount = self.unstructured.int_in_range(sys_call_amount_range)?; Ok((sys_call_amount != 0).then(|| { let call_indexes_handle = self.insert_sys_call_import(sys_call); @@ -280,9 +291,9 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { /// Returns the indexes of invocable sys-calls. fn invocable_sys_calls_indexes( - &self, + &mut self, sys_calls: &'static [SysCallName; N], - ) -> Result<[usize; N], RequiredSysCalls> { + ) -> [usize; N] { let mut indexes = [0; N]; for (index, &sys_call) in indexes.iter_mut().zip(sys_calls.iter()) { @@ -290,10 +301,16 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { .sys_calls_imports .get(&InvocableSysCall::Loose(sys_call)) .map(|&(_, call_indexes_handle)| call_indexes_handle) - .ok_or_else(|| RequiredSysCalls(&sys_calls[..]))?; + .unwrap_or_else(|| { + // insert required import when we can't find it + let call_indexes_handle = self.insert_sys_call_import(sys_call); + self.sys_calls_imports + .insert(InvocableSysCall::Loose(sys_call), (0, call_indexes_handle)); + call_indexes_handle + }) } - Ok(indexes) + indexes } /// Generates a function which calls "properly" the given sys-call. @@ -327,13 +344,12 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { log::trace!( "Built proper call to {precise_sys_call_name}", - precise_sys_call_name = InvocableSysCall::Precise(sys_call).to_str() + precise_sys_call_name = invocable_sys_call.to_str() ); let call_indexes_handle = self.call_indexes.len(); self.call_indexes.add_func(func_idx.signature as usize); - // TODO: make separate config for precise sys-calls (#3122) self.sys_calls_imports .insert(invocable_sys_call, (1, call_indexes_handle)); } @@ -355,15 +371,12 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { } /// Generates a function which calls "properly" the `gr_reservation_send`. - fn generate_send_from_reservation(&mut self) -> Result<(), PreciseSysCallError> { - const SYS_CALL: SysCallName = SysCallName::ReservationSend; - log::trace!( - "Constructing {name} sys-call...", - name = InvocableSysCall::Precise(SYS_CALL).to_str() - ); - + fn generate_send_from_reservation( + &mut self, + sys_call: SysCallName, + ) -> Result<(), PreciseSysCallError> { let [reserve_gas_idx, reservation_send_idx] = - self.invocable_sys_calls_indexes(&[SysCallName::ReserveGas, SYS_CALL])?; + self.invocable_sys_calls_indexes(InvocableSysCall::required_imports(sys_call)); // subtract to be sure we are in memory boundaries. let rid_pid_value_ptr = self.reserve_memory(); @@ -443,21 +456,18 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { Instruction::End, ]); - self.generate_proper_sys_call_invocation(SYS_CALL, func_instructions); + self.generate_proper_sys_call_invocation(sys_call, func_instructions); Ok(()) } /// Generates a function which calls "properly" the `gr_reservation_reply`. - fn generate_reply_from_reservation(&mut self) -> Result<(), PreciseSysCallError> { - const SYS_CALL: SysCallName = SysCallName::ReservationReply; - log::trace!( - "Constructing {name} sys-call...", - name = InvocableSysCall::Precise(SYS_CALL).to_str() - ); - + fn generate_reply_from_reservation( + &mut self, + sys_call: SysCallName, + ) -> Result<(), PreciseSysCallError> { let [reserve_gas_idx, reservation_reply_idx] = - self.invocable_sys_calls_indexes(&[SysCallName::ReserveGas, SYS_CALL])?; + self.invocable_sys_calls_indexes(InvocableSysCall::required_imports(sys_call)); // subtract to be sure we are in memory boundaries. let rid_value_ptr = self.reserve_memory(); @@ -518,25 +528,15 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { Instruction::End, ]); - self.generate_proper_sys_call_invocation(SYS_CALL, func_instructions); + self.generate_proper_sys_call_invocation(sys_call, func_instructions); Ok(()) } /// Generates a function which calls "properly" the `gr_send_commit`. - fn generate_send_commit(&mut self) -> Result<(), PreciseSysCallError> { - const SYS_CALL: SysCallName = SysCallName::SendCommit; - log::trace!( - "Constructing {name} sys-call...", - name = InvocableSysCall::Precise(SYS_CALL).to_str() - ); - + fn generate_send_commit(&mut self, sys_call: SysCallName) -> Result<(), PreciseSysCallError> { let [send_init_idx, send_push_idx, send_commit_idx] = - self.invocable_sys_calls_indexes(&[ - SysCallName::SendInit, - SysCallName::SendPush, - SYS_CALL, - ])?; + self.invocable_sys_calls_indexes(InvocableSysCall::required_imports(sys_call)); // subtract to be sure we are in memory boundaries. let handle_ptr = self.reserve_memory(); @@ -620,26 +620,18 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { let func_instructions = Instructions::new(elements); - self.generate_proper_sys_call_invocation(SYS_CALL, func_instructions); + self.generate_proper_sys_call_invocation(sys_call, func_instructions); Ok(()) } /// Generates a function which calls "properly" the `gr_send_commit_wgas`. - fn generate_send_commit_with_gas(&mut self) -> Result<(), PreciseSysCallError> { - const SYS_CALL: SysCallName = SysCallName::SendCommitWGas; - log::trace!( - "Constructing {name} sys-call...", - name = InvocableSysCall::Precise(SYS_CALL).to_str() - ); - - let [size_idx, send_init_idx, send_push_input_idx, send_commit_wgas_idx] = self - .invocable_sys_calls_indexes(&[ - SysCallName::Size, - SysCallName::SendInit, - SysCallName::SendPushInput, - SYS_CALL, - ])?; + fn generate_send_commit_with_gas( + &mut self, + sys_call: SysCallName, + ) -> Result<(), PreciseSysCallError> { + let [size_idx, send_init_idx, send_push_input_idx, send_commit_wgas_idx] = + self.invocable_sys_calls_indexes(InvocableSysCall::required_imports(sys_call)); // subtract to be sure we are in memory boundaries. let handle_ptr = self.reserve_memory(); @@ -730,7 +722,7 @@ impl<'a, 'b> SysCallsImportsGenerator<'a, 'b> { let func_instructions = Instructions::new(elements); - self.generate_proper_sys_call_invocation(SYS_CALL, func_instructions); + self.generate_proper_sys_call_invocation(sys_call, func_instructions); Ok(()) } diff --git a/utils/wasm-gen/src/tests.rs b/utils/wasm-gen/src/tests.rs index 78830b304e8..57019510d32 100644 --- a/utils/wasm-gen/src/tests.rs +++ b/utils/wasm-gen/src/tests.rs @@ -247,7 +247,11 @@ fn execute_wasm_with_syscall_injected( let mut unstructured = Unstructured::new(&buf); let mut injection_amounts = SysCallsInjectionAmounts::all_never(); - injection_amounts.set(syscall, INJECTED_SYSCALLS, INJECTED_SYSCALLS); + injection_amounts.set( + InvocableSysCall::Loose(syscall), + INJECTED_SYSCALLS, + INJECTED_SYSCALLS, + ); let error_processing_config = if ignore_fallible_errors { ErrorProcessingConfig::None