MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

prevent wasi from started unless reactor

+237 -4
+2
include/modules/wasi.h
··· 6 6 #include <stdint.h> 7 7 8 8 bool wasi_module_has_wasi_imports(void *c_api_module); 9 + bool wasi_module_is_command_or_reactor(void *c_api_module); 10 + bool wasi_bytes_need_wasi_command_warning_suppression(const uint8_t *wasm_bytes, size_t wasm_len); 9 11 10 12 ant_value_t wasi_instantiate( 11 13 ant_t *js, const uint8_t *wasm_bytes, size_t wasm_len,
+212
src/modules/wasi.c
··· 35 35 wasm_function_inst_t func; 36 36 } wasi_func_env_t; 37 37 38 + enum { 39 + WASM_SECTION_IMPORT = 2, 40 + WASM_SECTION_EXPORT = 7, 41 + }; 42 + 43 + static bool wasm_read_u32_leb(const uint8_t *buf, size_t len, size_t *offset, uint32_t *out) { 44 + uint32_t value = 0; 45 + uint32_t shift = 0; 46 + 47 + while (*offset < len && shift < 35) { 48 + uint8_t byte = buf[(*offset)++]; 49 + value |= (uint32_t)(byte & 0x7f) << shift; 50 + 51 + if ((byte & 0x80) == 0) { 52 + *out = value; 53 + return true; 54 + } 55 + 56 + shift += 7; 57 + } 58 + 59 + return false; 60 + } 61 + 62 + static bool wasm_read_name(const uint8_t *buf, size_t len, size_t *offset, const uint8_t **data, uint32_t *name_len) { 63 + uint32_t size = 0; 64 + 65 + if ( 66 + !wasm_read_u32_leb(buf, len, offset, &size) 67 + || *offset + size > len 68 + ) return false; 69 + 70 + *data = buf + *offset; 71 + *name_len = size; 72 + *offset += size; 73 + 74 + return true; 75 + } 76 + 77 + static bool wasm_name_equals(const uint8_t *data, uint32_t len, const char *expected) { 78 + size_t expected_len = strlen(expected); 79 + return len == expected_len && memcmp(data, expected, expected_len) == 0; 80 + } 81 + 82 + static bool wasi_bytes_have_wasi_imports(const uint8_t *wasm_bytes, size_t wasm_len) { 83 + size_t offset = 8; 84 + 85 + if (!wasm_bytes || wasm_len < 8 || memcmp(wasm_bytes, "\0asm\x01\0\0\0", 8) != 0) 86 + return false; 87 + 88 + while (offset < wasm_len) { 89 + uint8_t section_id = wasm_bytes[offset++]; 90 + uint32_t section_size = 0; 91 + const uint8_t *section; 92 + size_t section_offset = 0; 93 + size_t section_len; 94 + 95 + if ( 96 + !wasm_read_u32_leb(wasm_bytes, wasm_len, &offset, &section_size) 97 + || offset + section_size > wasm_len 98 + ) return false; 99 + 100 + section = wasm_bytes + offset; 101 + section_len = section_size; 102 + offset += section_size; 103 + 104 + if (section_id != WASM_SECTION_IMPORT) continue; 105 + if (!wasm_read_u32_leb(section, section_size, &section_offset, &section_size)) 106 + return false; 107 + 108 + for (uint32_t i = 0; i < section_size; i++) { 109 + const uint8_t *module_name = NULL; 110 + const uint8_t *field_name = NULL; 111 + uint32_t module_name_len = 0; 112 + uint32_t field_name_len = 0; 113 + uint32_t discard = 0; 114 + uint32_t flags = 0; 115 + 116 + if (!wasm_read_name(section, section_len, &section_offset, &module_name, &module_name_len) 117 + || !wasm_read_name(section, section_len, &section_offset, &field_name, &field_name_len) 118 + || section_offset >= section_len) 119 + return false; 120 + 121 + if (wasm_name_equals(module_name, module_name_len, "wasi_snapshot_preview1")) 122 + return true; 123 + 124 + switch (section[section_offset++]) { 125 + case 0: 126 + if (!wasm_read_u32_leb(section, section_len, &section_offset, &discard)) 127 + return false; 128 + break; 129 + case 1: { 130 + if (section_offset >= section_len) return false; 131 + section_offset++; 132 + if (!wasm_read_u32_leb(section, section_len, &section_offset, &flags) 133 + || !wasm_read_u32_leb(section, section_len, &section_offset, &discard)) 134 + return false; 135 + if ((flags & 0x1) != 0 136 + && !wasm_read_u32_leb(section, section_len, &section_offset, &discard)) 137 + return false; 138 + break; 139 + } 140 + case 2: 141 + if (!wasm_read_u32_leb(section, section_len, &section_offset, &flags) 142 + || !wasm_read_u32_leb(section, section_len, &section_offset, &discard)) 143 + return false; 144 + if ((flags & 0x1) != 0 145 + && !wasm_read_u32_leb(section, section_len, &section_offset, &discard)) 146 + return false; 147 + break; 148 + case 3: 149 + if (section_offset + 2 > section_len) return false; 150 + section_offset += 2; 151 + break; 152 + default: 153 + return false; 154 + } 155 + } 156 + } 157 + 158 + return false; 159 + } 160 + 161 + static bool wasi_bytes_have_command_or_reactor_entry(const uint8_t *wasm_bytes, size_t wasm_len) { 162 + size_t offset = 8; 163 + 164 + if (!wasm_bytes || wasm_len < 8 || memcmp(wasm_bytes, "\0asm\x01\0\0\0", 8) != 0) 165 + return false; 166 + 167 + while (offset < wasm_len) { 168 + uint8_t section_id = wasm_bytes[offset++]; 169 + uint32_t section_size = 0; 170 + const uint8_t *section; 171 + size_t section_offset = 0; 172 + size_t section_len; 173 + 174 + if (!wasm_read_u32_leb(wasm_bytes, wasm_len, &offset, &section_size) 175 + || offset + section_size > wasm_len) 176 + return false; 177 + 178 + section = wasm_bytes + offset; 179 + section_len = section_size; 180 + offset += section_size; 181 + 182 + if (section_id != WASM_SECTION_EXPORT) continue; 183 + if (!wasm_read_u32_leb(section, section_len, &section_offset, &section_size)) 184 + return false; 185 + 186 + for (uint32_t i = 0; i < section_size; i++) { 187 + const uint8_t *name = NULL; 188 + uint32_t name_len = 0; 189 + uint32_t discard = 0; 190 + 191 + if (!wasm_read_name(section, section_len, &section_offset, &name, &name_len) 192 + || section_offset >= section_len) 193 + return false; 194 + 195 + if (section[section_offset++] != 0) { 196 + if (!wasm_read_u32_leb(section, section_len, &section_offset, &discard)) 197 + return false; 198 + continue; 199 + } 200 + 201 + if (!wasm_read_u32_leb(section, section_len, &section_offset, &discard)) 202 + return false; 203 + 204 + if (wasm_name_equals(name, name_len, "_start") 205 + || wasm_name_equals(name, name_len, "_initialize")) 206 + return true; 207 + } 208 + } 209 + 210 + return false; 211 + } 212 + 38 213 static inline bool wasi_is_proc_exit_exception(const char *exception) { 39 214 return exception != NULL && strstr(exception, "wasi proc exit") != NULL; 40 215 } ··· 107 282 108 283 wasm_importtype_vec_delete(&import_types); 109 284 return has_wasi; 285 + } 286 + 287 + bool wasi_module_is_command_or_reactor(void *c_api_module) { 288 + wasm_exporttype_vec_t export_types = {0}; 289 + bool has_entry = false; 290 + 291 + wasm_module_exports((wasm_module_t *)c_api_module, &export_types); 292 + 293 + for (size_t i = 0; i < export_types.size; i++) { 294 + const wasm_name_t *name = wasm_exporttype_name(export_types.data[i]); 295 + const wasm_externtype_t *type = wasm_exporttype_type(export_types.data[i]); 296 + const wasm_functype_t *func_type; 297 + size_t name_len; 298 + 299 + if (!name || wasm_externtype_kind(type) != WASM_EXTERN_FUNC) continue; 300 + name_len = name->size; 301 + if (name_len > 0 && name->data[name_len - 1] == '\0') name_len--; 302 + 303 + if (!((name_len == 6 && memcmp(name->data, "_start", 6) == 0) 304 + || (name_len == 11 && memcmp(name->data, "_initialize", 11) == 0))) 305 + continue; 306 + 307 + func_type = wasm_externtype_as_functype_const(type); 308 + if (!func_type) continue; 309 + if (wasm_functype_params(func_type)->size == 0 && wasm_functype_results(func_type)->size == 0) { 310 + has_entry = true; 311 + break; 312 + } 313 + } 314 + 315 + wasm_exporttype_vec_delete(&export_types); 316 + return has_entry; 317 + } 318 + 319 + bool wasi_bytes_need_wasi_command_warning_suppression(const uint8_t *wasm_bytes, size_t wasm_len) { 320 + return wasi_bytes_have_wasi_imports(wasm_bytes, wasm_len) 321 + && !wasi_bytes_have_command_or_reactor_entry(wasm_bytes, wasm_len); 110 322 } 111 323 112 324 static void wasi_bind_func_export(
+23 -4
src/modules/wasm.c
··· 584 584 wasm_byte_vec_t binary = WASM_EMPTY_VEC; 585 585 wasm_store_t *store = NULL; 586 586 wasm_module_t *module = NULL; 587 + 587 588 char error_buf[128] = {0}; 589 + bool suppress_wasi_warning = false; 588 590 589 591 *out_module = js_mkundef(); 590 592 ··· 596 598 return js_mkerr_typed(js, JS_ERR_TYPE, "%s", error_buf); 597 599 } 598 600 601 + suppress_wasi_warning = wasi_bytes_need_wasi_command_warning_suppression( 602 + (const uint8_t *)binary.data, binary.size 603 + ); 604 + 605 + if (suppress_wasi_warning) wasm_runtime_set_log_level(WASM_LOG_LEVEL_ERROR); 599 606 module = wasm_module_new(store, &binary); 607 + 608 + if (suppress_wasi_warning) wasm_runtime_set_log_level(WASM_LOG_LEVEL_WARNING); 600 609 wasm_byte_vec_delete(&binary); 610 + 601 611 if (!module) { 602 612 wasm_store_delete(store); 603 613 return wasm_make_compile_error(js, "Failed to compile WebAssembly module"); ··· 768 778 wasm_instance_t *instance = NULL; 769 779 ant_value_t instance_obj = js_mkundef(); 770 780 ant_value_t exports_obj = js_mkobj(js); 771 - 772 781 *out_instance = js_mkundef(); 773 782 774 - if (!module_handle) return js_mkerr_typed(js, JS_ERR_TYPE, "Expected a WebAssembly.Module"); 783 + if (!module_handle) 784 + return js_mkerr_typed(js, JS_ERR_TYPE, "Expected a WebAssembly.Module"); 775 785 776 - if (wasi_module_has_wasi_imports(module_handle->module)) { 786 + if (wasi_module_has_wasi_imports(module_handle->module) 787 + && wasi_module_is_command_or_reactor(module_handle->module)) { 777 788 ant_value_t wasi_opts = is_object_type(import_obj) ? js_get(js, import_obj, "wasi") : js_mkundef(); 778 789 if (!is_object_type(import_obj) || is_object_type(wasi_opts)) { 779 790 ant_value_t bytes_src = js_get_slot(module_obj, SLOT_MAP); ··· 1205 1216 wasm_byte_vec_t binary = WASM_EMPTY_VEC; 1206 1217 wasm_store_t *store; 1207 1218 1219 + bool ok; 1208 1220 char error_buf[128] = {0}; 1209 - bool ok; 1221 + bool suppress_wasi_warning = false; 1210 1222 1211 1223 if (nargs < 1) return js_false; 1212 1224 if (!ensure_wasm_engine()) return js_false; ··· 1217 1229 return js_false; 1218 1230 } 1219 1231 1232 + suppress_wasi_warning = wasi_bytes_need_wasi_command_warning_suppression( 1233 + (const uint8_t *)binary.data, binary.size 1234 + ); 1235 + 1236 + if (suppress_wasi_warning) wasm_runtime_set_log_level(WASM_LOG_LEVEL_ERROR); 1220 1237 ok = wasm_module_validate(store, &binary); 1238 + 1239 + if (suppress_wasi_warning) wasm_runtime_set_log_level(WASM_LOG_LEVEL_WARNING); 1221 1240 wasm_byte_vec_delete(&binary); 1222 1241 wasm_store_delete(store); 1223 1242