wasm_mutator_fuzz.cc 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. // Copyright (C) 2019 Intel Corporation. All rights reserved.
  2. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  3. #include "wasm_runtime_common.h"
  4. #include "wasm_export.h"
  5. #include "bh_read_file.h"
  6. #include <stdlib.h>
  7. #include <stdio.h>
  8. #include <errno.h>
  9. #include <string.h>
  10. #include <iostream>
  11. #include <vector>
  12. using namespace std;
  13. extern "C" WASMModuleCommon *
  14. wasm_runtime_load(uint8 *buf, uint32 size, char *error_buf,
  15. uint32 error_buf_size);
  16. extern "C" WASMModuleInstanceCommon *
  17. wasm_runtime_instantiate(WASMModuleCommon *module, uint32 stack_size,
  18. uint32 heap_size, char *error_buf,
  19. uint32 error_buf_size);
  20. extern "C" int
  21. LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
  22. {
  23. /* libfuzzer don't allow us to modify the given Data, so we copy the data
  24. * here */
  25. std::vector<uint8_t> myData(Data, Data + Size);
  26. /* init runtime environment */
  27. wasm_runtime_init();
  28. wasm_module_t module =
  29. wasm_runtime_load((uint8_t *)myData.data(), Size, nullptr, 0);
  30. if (module) {
  31. wasm_runtime_unload(module);
  32. }
  33. /* destroy runtime environment */
  34. wasm_runtime_destroy();
  35. return 0; /* Values other than 0 and -1 are reserved for future use. */
  36. }
  37. /* Forward-declare the libFuzzer's mutator callback. */
  38. extern "C" size_t
  39. LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize);
  40. /* The custom mutator: */
  41. #ifdef CUSTOM_MUTATOR
  42. extern "C" size_t
  43. LLVMFuzzerCustomMutator(uint8_t *Data, size_t Size, size_t MaxSize,
  44. unsigned int Seed)
  45. {
  46. if ((NULL != Data) && (Size > 10)) {
  47. int mutate_ret = -1;
  48. /* delete */
  49. if (access("./cur.wasm", 0) == 0) {
  50. remove("./cur.wasm");
  51. }
  52. /* 1.write data to cur.wasm */
  53. FILE *fwrite_fp = fopen("./cur.wasm", "wb");
  54. if (NULL == fwrite_fp) {
  55. printf("Faild to open cur.wasm file!\n");
  56. return 0;
  57. }
  58. fwrite(Data, sizeof(uint8_t), Size, fwrite_fp);
  59. fclose(fwrite_fp);
  60. fwrite_fp = NULL;
  61. /* 2.wasm-tools mutate modify cur.wasm */
  62. char cmd_tmp[150] = { 0 };
  63. /* clang-format off */
  64. const char *preserve_semantic = (Seed % 2) ? "--preserve-semantics" : "";
  65. sprintf(cmd_tmp, "wasm-tools mutate cur.wasm --seed %d -o modified.wasm %s > /dev/null 2>&1", Seed, preserve_semantic);
  66. /* clang-format on */
  67. mutate_ret = system(cmd_tmp);
  68. memset(cmd_tmp, 0, sizeof(cmd_tmp));
  69. if (mutate_ret != 0) {
  70. /* If source file not valid, use libfuzzer's own modifier */
  71. return LLVMFuzzerMutate(Data, Size, MaxSize);
  72. }
  73. /* 3.read modified file */
  74. int read_len = 0;
  75. int file_len = 0;
  76. int res = 0;
  77. uint8_t *buf = NULL;
  78. FILE *fread_fp = fopen("./modified.wasm", "rb");
  79. if (NULL == fread_fp) {
  80. printf("Faild to open modified.wasm file!\n");
  81. exit(0);
  82. }
  83. fseek(fread_fp, 0, SEEK_END); /* location to file end */
  84. file_len = ftell(fread_fp); /* get file size */
  85. buf = (uint8_t *)malloc(file_len);
  86. if (NULL != buf) {
  87. fseek(fread_fp, 0, SEEK_SET); /* location to file start */
  88. read_len = fread(buf, 1, file_len, fread_fp);
  89. if ((read_len == file_len) && (read_len < MaxSize)) {
  90. /* 4.fill Data buffer */
  91. memcpy(Data, buf, read_len);
  92. res = read_len;
  93. }
  94. else {
  95. res = 0;
  96. }
  97. }
  98. else {
  99. res = 0;
  100. }
  101. memset(buf, 0, file_len);
  102. free(buf);
  103. fclose(fread_fp);
  104. fread_fp = NULL;
  105. return res;
  106. }
  107. else {
  108. if (access("./modified.wasm", 0) == 0) {
  109. remove("./modified.wasm");
  110. }
  111. memset(Data, 0, Size);
  112. Size = 0;
  113. return 0;
  114. }
  115. }
  116. #endif // CUSTOM_MUTATOR