فهرست منبع

Add integer overflow check for some indices in wasm/aot loader (#3579)

Check whether the indices overflow UINT32_MAX or not for:
- import function count + function count
- import global count + global count
- import tag count + tag count

This PR fixes the issue reported by Oss-fuzz test (#69920).
liang.he 1 سال پیش
والد
کامیت
f118492b1d

+ 7 - 0
core/iwasm/aot/aot_loader.c

@@ -2217,6 +2217,9 @@ load_global_info(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
     const uint8 *buf = *p_buf;
     const uint8 *buf = *p_buf;
 
 
     read_uint32(buf, buf_end, module->global_count);
     read_uint32(buf, buf_end, module->global_count);
+    if (is_indices_overflow(module->import_global_count, module->global_count,
+                            error_buf, error_buf_size))
+        return false;
 
 
     /* load globals */
     /* load globals */
     if (module->global_count > 0
     if (module->global_count > 0
@@ -2481,6 +2484,10 @@ load_init_data_section(const uint8 *buf, const uint8 *buf_end,
 
 
     /* load function count and start function index */
     /* load function count and start function index */
     read_uint32(p, p_end, module->func_count);
     read_uint32(p, p_end, module->func_count);
+    if (is_indices_overflow(module->import_func_count, module->func_count,
+                            error_buf, error_buf_size))
+        return false;
+
     read_uint32(p, p_end, module->start_func_index);
     read_uint32(p, p_end, module->start_func_index);
 
 
     /* check start function index */
     /* check start function index */

+ 17 - 0
core/iwasm/common/wasm_loader_common.c

@@ -96,3 +96,20 @@ is_valid_func_type(const WASMFuncType *func_type)
 
 
     return true;
     return true;
 }
 }
+
+/*
+ * Indices are represented as a u32.
+ */
+bool
+is_indices_overflow(uint32 import, uint32 other, char *error_buf,
+                    uint32 error_buf_size)
+{
+    if (import > UINT32_MAX - other) {
+        snprintf(error_buf, error_buf_size,
+                 "too many items in the index space(%" PRIu32 "+%" PRIu32 ").",
+                 import, other);
+        return true;
+    }
+
+    return false;
+}

+ 4 - 0
core/iwasm/common/wasm_loader_common.h

@@ -23,6 +23,10 @@ is_valid_value_type(uint8 value_tpye);
 bool
 bool
 is_valid_func_type(const WASMFuncType *func_type);
 is_valid_func_type(const WASMFuncType *func_type);
 
 
+bool
+is_indices_overflow(uint32 import, uint32 other, char *error_buf,
+                    uint32 error_buf_size);
+
 #ifdef __cplusplus
 #ifdef __cplusplus
 }
 }
 #endif
 #endif

+ 11 - 0
core/iwasm/interpreter/wasm_loader.c

@@ -3627,6 +3627,10 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
         return false;
         return false;
     }
     }
 
 
+    if (is_indices_overflow(module->import_function_count, func_count,
+                            error_buf, error_buf_size))
+        return false;
+
     if (func_count) {
     if (func_count) {
         module->function_count = func_count;
         module->function_count = func_count;
         total_size = sizeof(WASMFunction *) * (uint64)func_count;
         total_size = sizeof(WASMFunction *) * (uint64)func_count;
@@ -4022,6 +4026,9 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
 #endif
 #endif
 
 
     read_leb_uint32(p, p_end, global_count);
     read_leb_uint32(p, p_end, global_count);
+    if (is_indices_overflow(module->import_global_count, global_count,
+                            error_buf, error_buf_size))
+        return false;
 
 
     module->global_count = 0;
     module->global_count = 0;
     if (global_count) {
     if (global_count) {
@@ -4921,6 +4928,10 @@ load_tag_section(const uint8 *buf, const uint8 *buf_end, const uint8 *buf_code,
 
 
     /* get tag count */
     /* get tag count */
     read_leb_uint32(p, p_end, section_tag_count);
     read_leb_uint32(p, p_end, section_tag_count);
+    if (is_indices_overflow(module->import_tag_count, section_tag_count,
+                            error_buf, error_buf_size))
+        return false;
+
     module->tag_count = section_tag_count;
     module->tag_count = section_tag_count;
 
 
     if (section_tag_count) {
     if (section_tag_count) {

+ 4 - 0
core/iwasm/interpreter/wasm_mini_loader.c

@@ -1139,6 +1139,8 @@ load_function_section(const uint8 *buf, const uint8 *buf_end,
 
 
     bh_assert(func_count == code_count);
     bh_assert(func_count == code_count);
 
 
+    bh_assert(module->import_function_count <= UINT32_MAX - func_count);
+
     if (func_count) {
     if (func_count) {
         module->function_count = func_count;
         module->function_count = func_count;
         total_size = sizeof(WASMFunction *) * (uint64)func_count;
         total_size = sizeof(WASMFunction *) * (uint64)func_count;
@@ -1321,6 +1323,8 @@ load_global_section(const uint8 *buf, const uint8 *buf_end, WASMModule *module,
 
 
     read_leb_uint32(p, p_end, global_count);
     read_leb_uint32(p, p_end, global_count);
 
 
+    bh_assert(module->import_global_count <= UINT32_MAX - global_count);
+
     module->global_count = 0;
     module->global_count = 0;
     if (global_count) {
     if (global_count) {
         total_size = sizeof(WASMGlobal) * (uint64)global_count;
         total_size = sizeof(WASMGlobal) * (uint64)global_count;