Skip to content

Commit 11afe55

Browse files
authored
wasmer: initial integration (#9276)
Hi, [ Wasmer](https://github.com/wasmerio/wasmer) is a fast and secure [WebAssembly](https://webassembly.org/) runtime that enables super lightweight containers to run anywhere: from Desktop to the Cloud, Edge and IoT devices. - It has close to 2 million downloads as per [crates.io](https://crates.io/crates/wasmer). - It is being used by projects like: - [swc](https://github.com/swc-project/swc) - [zellij](https://github.com/zellij-org/zellij) - [youki](https://github.com/containers/youki) - [lunatic](https://github.com/lunatic-solutions/lunatic) - [mun](https://github.com/mun-lang/mun) - [locutus](https://github.com/freenet/locutus)
1 parent e5e1b3d commit 11afe55

9 files changed

+488
-0
lines changed

projects/wasmer/Dockerfile

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Copyright 2022 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
################################################################################
16+
17+
FROM gcr.io/oss-fuzz-base/base-builder-rust
18+
19+
RUN apt-get update && apt-get install -y make autoconf automake libtool \
20+
zlib1g-dev libffi-dev build-essential \
21+
clang-12 llvm-12 llvm-12-dev llvm-12-tools
22+
23+
RUN git clone --depth 1 https://github.com/wasmerio/wasmer wasmer
24+
25+
WORKDIR wasmer
26+
27+
COPY *.rs fuzz/fuzz_targets/
28+
COPY build.sh default.options $SRC/

projects/wasmer/build.sh

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#!/bin/bash -eu
2+
# Copyright 2022 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by ap plicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
################################################################################
17+
18+
export LLVM_SYS_120_PREFIX=$(llvm-config-12 --prefix)
19+
20+
cargo +nightly fuzz build universal_cranelift --features=universal,cranelift -O
21+
cargo +nightly fuzz build universal_llvm --features=universal,llvm -O
22+
cargo +nightly fuzz build universal_singlepass --features=universal,singlepass -O
23+
cargo +nightly fuzz build metering --features=universal,cranelift -O
24+
cargo +nightly fuzz build deterministic --features=universal,cranelift,llvm,singlepass -O
25+
26+
fuzz_targets="universal_cranelift \
27+
universal_llvm \
28+
universal_singlepass \
29+
metering \
30+
deterministic"
31+
fuzz_target_output_dir=target/x86_64-unknown-linux-gnu/release
32+
33+
for target in $fuzz_targets
34+
do
35+
cp $fuzz_target_output_dir/$target $OUT/
36+
cp $SRC/default.options $OUT/$target.options
37+
done

projects/wasmer/default.options

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[libfuzzer]
2+
detect_leaks=0

projects/wasmer/deterministic.rs

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
# Copyright 2022 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
################################################################################
17+
*/
18+
#![no_main]
19+
20+
use libfuzzer_sys::{arbitrary, arbitrary::Arbitrary, fuzz_target};
21+
use wasm_smith::{Config, ConfiguredModule};
22+
use wasmer::{CompilerConfig, Engine, EngineBuilder, Module, Store};
23+
use wasmer_compiler_cranelift::Cranelift;
24+
use wasmer_compiler_llvm::LLVM;
25+
use wasmer_compiler_singlepass::Singlepass;
26+
27+
#[derive(Arbitrary, Debug, Default, Copy, Clone)]
28+
struct NoImportsConfig;
29+
impl Config for NoImportsConfig {
30+
fn max_imports(&self) -> usize {
31+
0
32+
}
33+
fn max_memory_pages(&self) -> u32 {
34+
// https://github.com/wasmerio/wasmer/issues/2187
35+
65535
36+
}
37+
fn allow_start_export(&self) -> bool {
38+
false
39+
}
40+
}
41+
42+
fn compile_and_compare(name: &str, engine: Engine, wasm: &[u8]) {
43+
let store = Store::new(engine);
44+
45+
// compile for first time
46+
let module = Module::new(&store, wasm).unwrap();
47+
let first = module.serialize().unwrap();
48+
49+
// compile for second time
50+
let module = Module::new(&store, wasm).unwrap();
51+
let second = module.serialize().unwrap();
52+
53+
if first != second {
54+
panic!("non-deterministic compilation from {}", name);
55+
}
56+
}
57+
58+
fuzz_target!(|module: ConfiguredModule<NoImportsConfig>| {
59+
let wasm_bytes = module.to_bytes();
60+
61+
let mut compiler = Cranelift::default();
62+
compiler.canonicalize_nans(true);
63+
compiler.enable_verifier();
64+
compile_and_compare(
65+
"universal-cranelift",
66+
EngineBuilder::new(compiler.clone()).engine(),
67+
&wasm_bytes,
68+
);
69+
70+
let mut compiler = LLVM::default();
71+
compiler.canonicalize_nans(true);
72+
compiler.enable_verifier();
73+
compile_and_compare(
74+
"universal-llvm",
75+
EngineBuilder::new(compiler.clone()).engine(),
76+
&wasm_bytes,
77+
);
78+
79+
let compiler = Singlepass::default();
80+
compile_and_compare(
81+
"universal-singlepass",
82+
EngineBuilder::new(compiler.clone()).engine(),
83+
&wasm_bytes,
84+
);
85+
});

projects/wasmer/metering.rs

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
# Copyright 2022 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
################################################################################
17+
*/
18+
#![no_main]
19+
20+
use libfuzzer_sys::{arbitrary, arbitrary::Arbitrary, fuzz_target};
21+
use std::sync::Arc;
22+
use wasm_smith::{Config, ConfiguredModule};
23+
use wasmer::wasmparser::Operator;
24+
use wasmer::{imports, CompilerConfig, Instance, Module, Store};
25+
use wasmer_compiler_cranelift::Cranelift;
26+
use wasmer_middlewares::Metering;
27+
28+
#[derive(Arbitrary, Debug, Default, Copy, Clone)]
29+
struct NoImportsConfig;
30+
impl Config for NoImportsConfig {
31+
fn max_imports(&self) -> usize {
32+
0
33+
}
34+
fn max_memory_pages(&self) -> u32 {
35+
// https://github.com/wasmerio/wasmer/issues/2187
36+
65535
37+
}
38+
fn allow_start_export(&self) -> bool {
39+
false
40+
}
41+
}
42+
43+
#[derive(Arbitrary)]
44+
struct WasmSmithModule(ConfiguredModule<NoImportsConfig>);
45+
impl std::fmt::Debug for WasmSmithModule {
46+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47+
f.write_str(&wasmprinter::print_bytes(self.0.to_bytes()).unwrap())
48+
}
49+
}
50+
51+
fn cost(operator: &Operator) -> u64 {
52+
match operator {
53+
Operator::LocalGet { .. } | Operator::I32Const { .. } => 1,
54+
Operator::I32Add { .. } => 2,
55+
_ => 0,
56+
}
57+
}
58+
59+
fuzz_target!(|module: WasmSmithModule| {
60+
let wasm_bytes = module.0.to_bytes();
61+
62+
if let Ok(path) = std::env::var("DUMP_TESTCASE") {
63+
use std::fs::File;
64+
use std::io::Write;
65+
let mut file = File::create(path).unwrap();
66+
file.write_all(&wasm_bytes).unwrap();
67+
return;
68+
}
69+
70+
let mut compiler = Cranelift::default();
71+
compiler.canonicalize_nans(true);
72+
compiler.enable_verifier();
73+
let metering = Arc::new(Metering::new(10, cost));
74+
compiler.push_middleware(metering);
75+
let mut store = Store::new(compiler);
76+
let module = Module::new(&store, &wasm_bytes).unwrap();
77+
match Instance::new(&mut store, &module, &imports! {}) {
78+
Ok(_) => {}
79+
Err(e) => {
80+
let error_message = format!("{}", e);
81+
if error_message.starts_with("RuntimeError: ")
82+
&& error_message.contains("out of bounds")
83+
{
84+
return;
85+
}
86+
panic!("{}", e);
87+
}
88+
}
89+
});

projects/wasmer/project.yaml

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
homepage: "https://github.com/wasmerio/wasmer"
2+
language: rust
3+
main_repo: "https://github.com/wasmerio/wasmer"
4+
primary_contact: "[email protected]"
5+
auto_ccs:
6+
7+
8+
9+
sanitizers:
10+
- address
11+
fuzzing_engines:
12+
- libfuzzer
13+
vendor_ccs:
14+
+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
# Copyright 2022 Google LLC
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
#
16+
################################################################################
17+
*/
18+
#![no_main]
19+
20+
use libfuzzer_sys::{arbitrary, arbitrary::Arbitrary, fuzz_target};
21+
use wasm_smith::{Config, ConfiguredModule};
22+
use wasmer::{imports, CompilerConfig, Instance, Module, Store};
23+
use wasmer_compiler_cranelift::Cranelift;
24+
25+
#[derive(Arbitrary, Debug, Default, Copy, Clone)]
26+
struct NoImportsConfig;
27+
impl Config for NoImportsConfig {
28+
fn max_imports(&self) -> usize {
29+
0
30+
}
31+
fn max_memory_pages(&self) -> u32 {
32+
// https://github.com/wasmerio/wasmer/issues/2187
33+
65535
34+
}
35+
fn allow_start_export(&self) -> bool {
36+
false
37+
}
38+
}
39+
#[derive(Arbitrary)]
40+
struct WasmSmithModule(ConfiguredModule<NoImportsConfig>);
41+
impl std::fmt::Debug for WasmSmithModule {
42+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43+
f.write_str(&wasmprinter::print_bytes(self.0.to_bytes()).unwrap())
44+
}
45+
}
46+
47+
fuzz_target!(|module: WasmSmithModule| {
48+
let wasm_bytes = module.0.to_bytes();
49+
50+
if let Ok(path) = std::env::var("DUMP_TESTCASE") {
51+
use std::fs::File;
52+
use std::io::Write;
53+
let mut file = File::create(path).unwrap();
54+
file.write_all(&wasm_bytes).unwrap();
55+
return;
56+
}
57+
58+
let mut compiler = Cranelift::default();
59+
compiler.canonicalize_nans(true);
60+
compiler.enable_verifier();
61+
let mut store = Store::new(compiler);
62+
let module = Module::new(&store, &wasm_bytes).unwrap();
63+
match Instance::new(&mut store, &module, &imports! {}) {
64+
Ok(_) => {}
65+
Err(e) => {
66+
let error_message = format!("{}", e);
67+
if error_message.starts_with("RuntimeError: ")
68+
&& error_message.contains("out of bounds")
69+
{
70+
return;
71+
}
72+
panic!("{}", e);
73+
}
74+
}
75+
});

0 commit comments

Comments
 (0)