/src/wasm3/platforms/app_fuzz/fuzzer.c
Line | Count | Source |
1 | | // |
2 | | // Wasm3 - high performance WebAssembly interpreter written in C. |
3 | | // |
4 | | // Copyright © 2019 Steven Massey, Volodymyr Shymanskyy. |
5 | | // All rights reserved. |
6 | | // |
7 | | |
8 | | #include <stdint.h> |
9 | | #include <stddef.h> |
10 | | |
11 | | #include "wasm3.h" |
12 | | #include "m3_env.h" // for IM3Runtime::memoryLimit |
13 | | |
14 | | #define FATAL(...) __builtin_trap() |
15 | | |
16 | | // A module may declare up to 4 GiB of linear memory, and wasm3 allocates the |
17 | | // initial pages eagerly at load, so a handful of bytes can ask for more than |
18 | | // the fuzzing engine allows and get killed as an OOM rather than exercising |
19 | | // anything. Cap what is actually allocated: memory accesses and data segment |
20 | | // loads are bounded by the allocated length, not the declared page count. |
21 | 1.89k | #define d_m3FuzzMemoryLimit (64*1024*1024) |
22 | | |
23 | | // Nothing stops a few fuzzed bytes from describing a loop that never ends. |
24 | | // Fuzzer timeout is an error => let's use gas metering to limit the number |
25 | | // of instructions that can run. |
26 | 1.89k | #define d_m3FuzzGasLimit 100000.0 |
27 | | |
28 | | int LLVMFuzzerTestOneInput (const uint8_t* data, size_t size) |
29 | 1.89k | { |
30 | 1.89k | M3Result result = m3Err_none; |
31 | | |
32 | 1.89k | if (size < 8 || size > 256 * 1024) { |
33 | 1 | return 0; |
34 | 1 | } |
35 | | |
36 | 1.89k | IM3Environment env = m3_NewEnvironment(); |
37 | 1.89k | if (env) { |
38 | 1.89k | IM3Runtime runtime = m3_NewRuntime(env, 128, NULL); |
39 | 1.89k | if (runtime) { |
40 | 1.89k | runtime->memoryLimit = d_m3FuzzMemoryLimit; |
41 | 1.89k | IM3Module module = NULL; |
42 | | |
43 | 1.89k | m3_SetGasLimit(runtime, d_m3FuzzGasLimit); |
44 | | |
45 | 1.89k | result = m3_ParseModule(env, &module, data, size); |
46 | 1.89k | if (module) { |
47 | 1.60k | result = m3_LoadModule(runtime, module); |
48 | 1.60k | if (result == 0) { |
49 | 1.56k | IM3Function f = NULL; |
50 | | |
51 | 1.56k | result = m3_FindFunction(&f, runtime, "fib"); |
52 | 1.56k | if (f) { |
53 | 467 | m3_CallV(f, 10); |
54 | 467 | } |
55 | 1.56k | } |
56 | | // on failure too, the runtime owns the module now |
57 | 1.60k | } |
58 | | |
59 | 1.89k | m3_FreeRuntime(runtime); |
60 | 1.89k | } |
61 | 1.89k | m3_FreeEnvironment(env); |
62 | 1.89k | } |
63 | | |
64 | 1.89k | return 0; |
65 | 1.89k | } |