Skip to content

(Partially) Enable reference-types again #2443

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: co/update-wasmer
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,8 @@ jobs:

contract_hackatom:
docker:
- image: rust:1.81
# We compile this contract with the upper bound to detect issues with new Rust versions early
- image: rust:1.84.1
environment:
RUST_BACKTRACE: 1
working_directory: ~/cosmwasm/contracts/hackatom
Expand All @@ -743,9 +744,9 @@ jobs:
command: rustc --version; cargo --version; rustup --version
- restore_cache:
keys:
- cargocache-v2-contract_hackatom-rust:1.81-{{ checksum "Cargo.lock" }}
- cargocache-v2-contract_hackatom-rust:1.84.1-{{ checksum "Cargo.lock" }}
- check_contract:
min_version: "2.2"
min_version: "3.0"
- save_cache:
paths:
- /usr/local/cargo/registry
Expand All @@ -755,7 +756,7 @@ jobs:
- target/wasm32-unknown-unknown/release/.fingerprint
- target/wasm32-unknown-unknown/release/build
- target/wasm32-unknown-unknown/release/deps
key: cargocache-v2-contract_hackatom-rust:1.81-{{ checksum "Cargo.lock" }}
key: cargocache-v2-contract_hackatom-rust:1.84.1-{{ checksum "Cargo.lock" }}

contract_ibc_callbacks:
docker:
Expand Down
3 changes: 2 additions & 1 deletion packages/vm/src/parsed_wasm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ impl<'a> ParsedWasm<'a> {
| WasmFeatures::SATURATING_FLOAT_TO_INT
| WasmFeatures::SIGN_EXTENSION
| WasmFeatures::MULTI_VALUE
| WasmFeatures::FLOATS;
| WasmFeatures::FLOATS
| WasmFeatures::REFERENCE_TYPES;

let mut validator = Validator::new_with_features(features);

Expand Down
13 changes: 13 additions & 0 deletions packages/vm/src/wasm_backend/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,17 @@ mod tests {
let engine = make_compiling_engine(None);
assert!(compile(&engine, FLOATY).is_ok());
}

#[test]
fn reference_types_dont_panic() {
const WASM: &str = r#"(module
(type $t0 (func (param funcref externref)))
(import "" "" (func $hello (type $t0)))
)"#;

let wasm = wat::parse_str(WASM).unwrap();
let engine = make_compiling_engine(None);
let error = compile(&engine, &wasm).unwrap_err();
assert!(error.to_string().contains("FuncRef"));
}
}
54 changes: 53 additions & 1 deletion packages/vm/src/wasm_backend/gatekeeper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,12 @@ impl Default for Gatekeeper {
fn default() -> Self {
Self::new(GatekeeperConfig {
allow_floats: true,
allow_feature_bulk_memory_operations: false,
// we allow the reference types proposal during compatibility checking because a subset
// of it is required since Rust 1.82, but we don't allow any of the instructions specific
// to the proposal here. Especially `table.grow` and `table.fill` can be abused to cause
// very long runtime and high memory usage.
allow_feature_reference_types: false,
allow_feature_bulk_memory_operations: false,
allow_feature_simd: false,
allow_feature_exception_handling: false,
allow_feature_threads: false,
Expand Down Expand Up @@ -461,4 +465,52 @@ mod tests {
.to_string()
.contains("Bulk memory operation"));
}

#[test]
fn bulk_table_operations_not_supported() {
// these operations can take a long time with big tables
let deterministic = Arc::new(Gatekeeper::default());
let mut compiler = make_compiler_config();
compiler.push_middleware(deterministic);
let store = Store::new(compiler);

let wasm = wat::parse_str(
r#"
(module
(table 2 funcref)
(func (export "test") (param $i i32) (result i32)
;; grow table to size of $i
ref.null func
local.get $i
table.grow 0))
"#,
)
.unwrap();

let result = Module::new(&store, wasm);
assert!(result
.unwrap_err()
.to_string()
.contains("Reference type operation"));

let wasm = wat::parse_str(
r#"
(module
(table 1000000000 funcref)
(func (export "test") (param $i i32)
;; fill with nulls
i32.const 0
ref.null func
i32.const 1000000000
table.fill 0))
"#,
)
.unwrap();

let result = Module::new(&store, wasm);
assert!(result
.unwrap_err()
.to_string()
.contains("Reference type operation"));
}
}
Loading