Add wasm-mutator-fuzz test (#3420)
This commit is contained in:
138
tests/fuzz/wasm-mutator-fuzz/workspace/CMakeLists.txt
Normal file
138
tests/fuzz/wasm-mutator-fuzz/workspace/CMakeLists.txt
Normal file
@ -0,0 +1,138 @@
|
||||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
cmake_minimum_required (VERSION 2.8)
|
||||
|
||||
project(wasm_mutator)
|
||||
|
||||
add_definitions(-DUNIT_TEST)
|
||||
|
||||
set (CMAKE_BUILD_TYPE Debug)
|
||||
|
||||
set (CMAKE_C_COMPILER "clang")
|
||||
set (CMAKE_CXX_COMPILER "clang++")
|
||||
|
||||
set (WAMR_BUILD_PLATFORM "linux")
|
||||
|
||||
# Reset default linker flags
|
||||
set (CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
|
||||
set (CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "")
|
||||
|
||||
set (CMAKE_C_STANDARD 99)
|
||||
|
||||
# Set WAMR_BUILD_TARGET, currently values supported:
|
||||
# "X86_64", "AMD_64", "X86_32", "AARCH64[sub]", "ARM[sub]", "THUMB[sub]",
|
||||
# "MIPS", "XTENSA", "RISCV64[sub]", "RISCV32[sub]"
|
||||
if (NOT DEFINED WAMR_BUILD_TARGET)
|
||||
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm64|aarch64)")
|
||||
set (WAMR_BUILD_TARGET "AARCH64")
|
||||
elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "riscv64")
|
||||
set (WAMR_BUILD_TARGET "RISCV64")
|
||||
elseif (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
# Build as X86_64 by default in 64-bit platform
|
||||
set (WAMR_BUILD_TARGET "X86_64")
|
||||
elseif (CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
# Build as X86_32 by default in 32-bit platform
|
||||
set (WAMR_BUILD_TARGET "X86_32")
|
||||
else ()
|
||||
message(SEND_ERROR "Unsupported build target platform!")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if(CUSTOM_MUTATOR EQUAL 1)
|
||||
add_compile_definitions(CUSTOM_MUTATOR)
|
||||
endif()
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_INTERP)
|
||||
# Enable Interpreter by default
|
||||
set (WAMR_BUILD_INTERP 1)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_AOT)
|
||||
# Enable AOT by default.
|
||||
set (WAMR_BUILD_AOT 1)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_JIT)
|
||||
# Disable JIT by default.
|
||||
set (WAMR_BUILD_JIT 0)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_LIBC_BUILTIN)
|
||||
# Enable libc builtin support by default
|
||||
set (WAMR_BUILD_LIBC_BUILTIN 1)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_LIBC_WASI)
|
||||
# Enable libc wasi support by default
|
||||
set (WAMR_BUILD_LIBC_WASI 1)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_FAST_INTERP)
|
||||
# Enable fast interpreter
|
||||
set (WAMR_BUILD_FAST_INTERP 1)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_MULTI_MODULE)
|
||||
# Enable multiple modules
|
||||
set (WAMR_BUILD_MULTI_MODULE 0)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_LIB_PTHREAD)
|
||||
# Disable pthread library by default
|
||||
set (WAMR_BUILD_LIB_PTHREAD 0)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_MINI_LOADER)
|
||||
# Disable wasm mini loader by default
|
||||
set (WAMR_BUILD_MINI_LOADER 0)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_SIMD)
|
||||
# Enable SIMD by default
|
||||
set (WAMR_BUILD_SIMD 1)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_REF_TYPES)
|
||||
# Disable reference types by default
|
||||
set (WAMR_BUILD_REF_TYPES 0)
|
||||
endif ()
|
||||
|
||||
if (NOT DEFINED WAMR_BUILD_DEBUG_INTERP)
|
||||
# Disable Debug feature by default
|
||||
set (WAMR_BUILD_DEBUG_INTERP 0)
|
||||
endif ()
|
||||
|
||||
if (WAMR_BUILD_DEBUG_INTERP EQUAL 1)
|
||||
set (WAMR_BUILD_FAST_INTERP 0)
|
||||
set (WAMR_BUILD_MINI_LOADER 0)
|
||||
set (WAMR_BUILD_SIMD 0)
|
||||
endif ()
|
||||
|
||||
set (REPO_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../../../..)
|
||||
message([ceith]:REPO_ROOT_DIR, ${REPO_ROOT_DIR})
|
||||
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||
|
||||
add_definitions(-DWAMR_USE_MEM_POOL=0)
|
||||
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -fsanitize=signed-integer-overflow \
|
||||
-fprofile-instr-generate -fcoverage-mapping \
|
||||
-fsanitize=address,undefined,fuzzer")
|
||||
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -fsanitize=signed-integer-overflow \
|
||||
-fprofile-instr-generate -fcoverage-mapping \
|
||||
-fsanitize=address,undefined,fuzzer")
|
||||
|
||||
include(${REPO_ROOT_DIR}/wamr/core/shared/utils/uncommon/shared_uncommon.cmake)
|
||||
include(${REPO_ROOT_DIR}/wamr/build-scripts/runtime_lib.cmake)
|
||||
|
||||
add_library(vmlib
|
||||
${WAMR_RUNTIME_LIB_SOURCE}
|
||||
)
|
||||
|
||||
add_executable(wasm_mutator_fuzz wasm_mutator_fuzz.cc)
|
||||
target_link_libraries(wasm_mutator_fuzz vmlib -lm)
|
||||
133
tests/fuzz/wasm-mutator-fuzz/workspace/wasm_mutator_fuzz.cc
Normal file
133
tests/fuzz/wasm-mutator-fuzz/workspace/wasm_mutator_fuzz.cc
Normal file
@ -0,0 +1,133 @@
|
||||
// Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
#include "wasm_runtime_common.h"
|
||||
#include "wasm_export.h"
|
||||
#include "bh_read_file.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern "C" WASMModuleCommon *
|
||||
wasm_runtime_load(uint8 *buf, uint32 size, char *error_buf,
|
||||
uint32 error_buf_size);
|
||||
|
||||
extern "C" WASMModuleInstanceCommon *
|
||||
wasm_runtime_instantiate(WASMModuleCommon *module, uint32 stack_size,
|
||||
uint32 heap_size, char *error_buf,
|
||||
uint32 error_buf_size);
|
||||
|
||||
extern "C" int
|
||||
LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
||||
{
|
||||
/* libfuzzer don't allow us to modify the given Data, so we copy the data
|
||||
* here */
|
||||
std::vector<uint8_t> myData(Data, Data + Size);
|
||||
/* init runtime environment */
|
||||
wasm_runtime_init();
|
||||
wasm_module_t module =
|
||||
wasm_runtime_load((uint8_t *)myData.data(), Size, nullptr, 0);
|
||||
if (module) {
|
||||
wasm_runtime_unload(module);
|
||||
}
|
||||
/* destroy runtime environment */
|
||||
wasm_runtime_destroy();
|
||||
|
||||
return 0; /* Values other than 0 and -1 are reserved for future use. */
|
||||
}
|
||||
|
||||
/* Forward-declare the libFuzzer's mutator callback. */
|
||||
extern "C" size_t
|
||||
LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize);
|
||||
|
||||
/* The custom mutator: */
|
||||
#ifdef CUSTOM_MUTATOR
|
||||
extern "C" size_t
|
||||
LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size, size_t MaxSize,
|
||||
unsigned int Seed)
|
||||
{
|
||||
if ((NULL != Data) && (Size > 10)) {
|
||||
int mutate_ret = -1;
|
||||
/* delete */
|
||||
if (access("./cur.wasm", 0) == 0) {
|
||||
remove("./cur.wasm");
|
||||
}
|
||||
|
||||
/* 1.write data to cur.wasm */
|
||||
FILE *fwrite_fp = fopen("./cur.wasm", "wb");
|
||||
if (NULL == fwrite_fp) {
|
||||
printf("Faild to open cur.wasm file!\n");
|
||||
return 0;
|
||||
}
|
||||
fwrite(Data, sizeof(uint8_t), Size, fwrite_fp);
|
||||
fclose(fwrite_fp);
|
||||
fwrite_fp = NULL;
|
||||
|
||||
/* 2.wasm-tools mutate modify cur.wasm */
|
||||
char cmd_tmp[150] = { 0 };
|
||||
|
||||
/* clang-format off */
|
||||
const char *preserve_semantic = (Seed % 2) ? "--preserve-semantics" : "";
|
||||
sprintf(cmd_tmp, "wasm-tools mutate cur.wasm --seed %d -o modified.wasm %s > /dev/null 2>&1", Seed, preserve_semantic);
|
||||
/* clang-format on */
|
||||
mutate_ret = system(cmd_tmp);
|
||||
memset(cmd_tmp, 0, sizeof(cmd_tmp));
|
||||
|
||||
if (mutate_ret != 0) {
|
||||
/* If source file not valid, use libfuzzer's own modifier */
|
||||
return LLVMFuzzerMutate(Data, Size, MaxSize);
|
||||
}
|
||||
|
||||
/* 3.read modified file */
|
||||
int read_len = 0;
|
||||
int file_len = 0;
|
||||
int res = 0;
|
||||
uint8_t *buf = NULL;
|
||||
FILE *fread_fp = fopen("./modified.wasm", "rb");
|
||||
if (NULL == fread_fp) {
|
||||
printf("Faild to open modified.wasm file!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
fseek(fread_fp, 0, SEEK_END); /* location to file end */
|
||||
file_len = ftell(fread_fp); /* get file size */
|
||||
buf = (uint8_t *)malloc(file_len);
|
||||
|
||||
if (NULL != buf) {
|
||||
fseek(fread_fp, 0, SEEK_SET); /* location to file start */
|
||||
read_len = fread(buf, 1, file_len, fread_fp);
|
||||
if ((read_len == file_len) && (read_len < MaxSize)) {
|
||||
/* 4.fill Data buffer */
|
||||
memcpy(Data, buf, read_len);
|
||||
res = read_len;
|
||||
}
|
||||
else {
|
||||
res = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
res = 0;
|
||||
}
|
||||
|
||||
memset(buf, 0, file_len);
|
||||
free(buf);
|
||||
fclose(fread_fp);
|
||||
fread_fp = NULL;
|
||||
|
||||
return res;
|
||||
}
|
||||
else {
|
||||
if (access("./modified.wasm", 0) == 0) {
|
||||
remove("./modified.wasm");
|
||||
}
|
||||
memset(Data, 0, Size);
|
||||
Size = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif // CUSTOM_MUTATOR
|
||||
Reference in New Issue
Block a user