mirror of
				https://github.com/bytecodealliance/wasm-micro-runtime.git
				synced 2025-10-31 13:17:31 +00:00 
			
		
		
		
	Fix some check issues on table operations (#2392)
Fix some check issues on table.init, table.fill and table.copy, and unify the check method for all running modes. Fix issue #2390 and #2096.
This commit is contained in:
		
							parent
							
								
									228417ab8c
								
							
						
					
					
						commit
						59b2099b68
					
				|  | @ -2489,13 +2489,13 @@ aot_table_init(AOTModuleInstance *module_inst, uint32 tbl_idx, | |||
|     tbl_seg = module->table_init_data_list[tbl_seg_idx]; | ||||
|     bh_assert(tbl_seg); | ||||
| 
 | ||||
|     if (!length) { | ||||
|     if (offset_len_out_of_bounds(src_offset, length, tbl_seg->func_index_count) | ||||
|         || offset_len_out_of_bounds(dst_offset, length, tbl_inst->cur_size)) { | ||||
|         aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (length + src_offset > tbl_seg->func_index_count | ||||
|         || dst_offset + length > tbl_inst->cur_size) { | ||||
|         aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS); | ||||
|     if (!length) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|  | @ -2528,8 +2528,9 @@ aot_table_copy(AOTModuleInstance *module_inst, uint32 src_tbl_idx, | |||
|     dst_tbl_inst = module_inst->tables[dst_tbl_idx]; | ||||
|     bh_assert(dst_tbl_inst); | ||||
| 
 | ||||
|     if ((uint64)dst_offset + length > dst_tbl_inst->cur_size | ||||
|         || (uint64)src_offset + length > src_tbl_inst->cur_size) { | ||||
|     if (offset_len_out_of_bounds(dst_offset, length, dst_tbl_inst->cur_size) | ||||
|         || offset_len_out_of_bounds(src_offset, length, | ||||
|                                     src_tbl_inst->cur_size)) { | ||||
|         aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS); | ||||
|         return; | ||||
|     } | ||||
|  | @ -2554,7 +2555,7 @@ aot_table_fill(AOTModuleInstance *module_inst, uint32 tbl_idx, uint32 length, | |||
|     tbl_inst = module_inst->tables[tbl_idx]; | ||||
|     bh_assert(tbl_inst); | ||||
| 
 | ||||
|     if (data_offset + length > tbl_inst->cur_size) { | ||||
|     if (offset_len_out_of_bounds(data_offset, length, tbl_inst->cur_size)) { | ||||
|         aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS); | ||||
|         return; | ||||
|     } | ||||
|  |  | |||
|  | @ -88,27 +88,28 @@ fail: | |||
| 
 | ||||
| static int | ||||
| wasm_init_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 elem_idx, | ||||
|                 uint32 dst, uint32 len, uint32 src) | ||||
|                 uint32 dst_offset, uint32 len, uint32 src_offset) | ||||
| { | ||||
|     WASMTableInstance *tbl; | ||||
|     uint32 tbl_sz; | ||||
|     WASMTableSeg *elem; | ||||
|     uint32 elem_len; | ||||
| 
 | ||||
|     tbl = inst->tables[tbl_idx]; | ||||
|     tbl_sz = tbl->cur_size; | ||||
|     if (dst > tbl_sz || tbl_sz - dst < len) | ||||
|         goto out_of_bounds; | ||||
| 
 | ||||
|     elem = inst->module->table_segments + elem_idx; | ||||
|     elem_len = elem->function_count; | ||||
|     if (src > elem_len || elem_len - src < len) | ||||
|     if (offset_len_out_of_bounds(src_offset, len, elem_len)) | ||||
|         goto out_of_bounds; | ||||
| 
 | ||||
|     tbl = inst->tables[tbl_idx]; | ||||
|     tbl_sz = tbl->cur_size; | ||||
|     if (offset_len_out_of_bounds(dst_offset, len, tbl_sz)) | ||||
|         goto out_of_bounds; | ||||
| 
 | ||||
|     bh_memcpy_s((uint8 *)tbl + offsetof(WASMTableInstance, elems) | ||||
|                     + dst * sizeof(uint32), | ||||
|                 (uint32)((tbl_sz - dst) * sizeof(uint32)), | ||||
|                 elem->func_indexes + src, (uint32)(len * sizeof(uint32))); | ||||
|                     + dst_offset * sizeof(uint32), | ||||
|                 (uint32)((tbl_sz - dst_offset) * sizeof(uint32)), | ||||
|                 elem->func_indexes + src_offset, | ||||
|                 (uint32)(len * sizeof(uint32))); | ||||
| 
 | ||||
|     return 0; | ||||
| out_of_bounds: | ||||
|  | @ -157,14 +158,14 @@ wasm_copy_table(WASMModuleInstance *inst, uint32 src_tbl_idx, | |||
|     WASMTableInstance *src_tbl, *dst_tbl; | ||||
|     uint32 src_tbl_sz, dst_tbl_sz; | ||||
| 
 | ||||
|     src_tbl = inst->tables[src_tbl_idx]; | ||||
|     src_tbl_sz = src_tbl->cur_size; | ||||
|     if (src_offset > src_tbl_sz || src_tbl_sz - src_offset < len) | ||||
|         goto out_of_bounds; | ||||
| 
 | ||||
|     dst_tbl = inst->tables[dst_tbl_idx]; | ||||
|     dst_tbl_sz = dst_tbl->cur_size; | ||||
|     if (dst_offset > dst_tbl_sz || dst_tbl_sz - dst_offset < len) | ||||
|     if (offset_len_out_of_bounds(dst_offset, len, dst_tbl_sz)) | ||||
|         goto out_of_bounds; | ||||
| 
 | ||||
|     src_tbl = inst->tables[src_tbl_idx]; | ||||
|     src_tbl_sz = src_tbl->cur_size; | ||||
|     if (offset_len_out_of_bounds(src_offset, len, src_tbl_sz)) | ||||
|         goto out_of_bounds; | ||||
| 
 | ||||
|     bh_memmove_s((uint8 *)dst_tbl + offsetof(WASMTableInstance, elems) | ||||
|  | @ -263,7 +264,7 @@ fail: | |||
| } | ||||
| 
 | ||||
| static int | ||||
| wasm_fill_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 dst, | ||||
| wasm_fill_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 dst_offset, | ||||
|                 uint32 val, uint32 len) | ||||
| { | ||||
|     WASMTableInstance *tbl; | ||||
|  | @ -272,11 +273,11 @@ wasm_fill_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 dst, | |||
|     tbl = inst->tables[tbl_idx]; | ||||
|     tbl_sz = tbl->cur_size; | ||||
| 
 | ||||
|     if (dst > tbl_sz || tbl_sz - dst < len) | ||||
|     if (offset_len_out_of_bounds(dst_offset, len, tbl_sz)) | ||||
|         goto out_of_bounds; | ||||
| 
 | ||||
|     for (; len != 0; dst++, len--) { | ||||
|         tbl->elems[dst] = val; | ||||
|     for (; len != 0; dst_offset++, len--) { | ||||
|         tbl->elems[dst_offset] = val; | ||||
|     } | ||||
| 
 | ||||
|     return 0; | ||||
|  |  | |||
|  | @ -627,7 +627,6 @@ typedef struct WASMBranchBlock { | |||
|     uint32 cell_num; | ||||
| } WASMBranchBlock; | ||||
| 
 | ||||
| /* Execution environment, e.g. stack info */ | ||||
| /**
 | ||||
|  * Align an unsigned value on a alignment boundary. | ||||
|  * | ||||
|  | @ -643,6 +642,24 @@ align_uint(unsigned v, unsigned b) | |||
|     return (v + m) & ~m; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Check whether a piece of data is out of range | ||||
|  * | ||||
|  * @param offset the offset that the data starts | ||||
|  * @param len the length of the data | ||||
|  * @param max_size the maximum size of the data range | ||||
|  * | ||||
|  * @return true if out of range, false otherwise | ||||
|  */ | ||||
| inline static bool | ||||
| offset_len_out_of_bounds(uint32 offset, uint32 len, uint32 max_size) | ||||
| { | ||||
|     if (offset + len < offset /* integer overflow */ | ||||
|         || offset + len > max_size) | ||||
|         return true; | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| /**
 | ||||
|  * Return the hash value of c string. | ||||
|  */ | ||||
|  |  | |||
|  | @ -3247,7 +3247,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, | |||
|                     case WASM_OP_TABLE_INIT: | ||||
|                     { | ||||
|                         uint32 tbl_idx, elem_idx; | ||||
|                         uint64 n, s, d; | ||||
|                         uint32 n, s, d; | ||||
|                         WASMTableInstance *tbl_inst; | ||||
| 
 | ||||
|                         read_leb_uint32(frame_ip, frame_ip_end, elem_idx); | ||||
|  | @ -3262,20 +3262,21 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, | |||
|                         s = (uint32)POP_I32(); | ||||
|                         d = (uint32)POP_I32(); | ||||
| 
 | ||||
|                         /* TODO: what if the element is not passive? */ | ||||
| 
 | ||||
|                         if (!n) { | ||||
|                             break; | ||||
|                         } | ||||
| 
 | ||||
|                         if (n + s > module->module->table_segments[elem_idx] | ||||
|                                         .function_count | ||||
|                             || d + n > tbl_inst->cur_size) { | ||||
|                         if (offset_len_out_of_bounds( | ||||
|                                 s, n, | ||||
|                                 module->module->table_segments[elem_idx] | ||||
|                                     .function_count) | ||||
|                             || offset_len_out_of_bounds(d, n, | ||||
|                                                         tbl_inst->cur_size)) { | ||||
|                             wasm_set_exception(module, | ||||
|                                                "out of bounds table access"); | ||||
|                             goto got_exception; | ||||
|                         } | ||||
| 
 | ||||
|                         if (!n) { | ||||
|                             break; | ||||
|                         } | ||||
| 
 | ||||
|                         if (module->module->table_segments[elem_idx] | ||||
|                                 .is_dropped) { | ||||
|                             wasm_set_exception(module, | ||||
|  | @ -3316,7 +3317,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, | |||
|                     case WASM_OP_TABLE_COPY: | ||||
|                     { | ||||
|                         uint32 src_tbl_idx, dst_tbl_idx; | ||||
|                         uint64 n, s, d; | ||||
|                         uint32 n, s, d; | ||||
|                         WASMTableInstance *src_tbl_inst, *dst_tbl_inst; | ||||
| 
 | ||||
|                         read_leb_uint32(frame_ip, frame_ip_end, dst_tbl_idx); | ||||
|  | @ -3333,8 +3334,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, | |||
|                         s = (uint32)POP_I32(); | ||||
|                         d = (uint32)POP_I32(); | ||||
| 
 | ||||
|                         if (d + n > dst_tbl_inst->cur_size | ||||
|                             || s + n > src_tbl_inst->cur_size) { | ||||
|                         if (offset_len_out_of_bounds(d, n, | ||||
|                                                      dst_tbl_inst->cur_size) | ||||
|                             || offset_len_out_of_bounds( | ||||
|                                 s, n, src_tbl_inst->cur_size)) { | ||||
|                             wasm_set_exception(module, | ||||
|                                                "out of bounds table access"); | ||||
|                             goto got_exception; | ||||
|  | @ -3404,11 +3407,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, | |||
|                         fill_val = POP_I32(); | ||||
|                         i = POP_I32(); | ||||
| 
 | ||||
|                         /* TODO: what if the element is not passive? */ | ||||
|                         /* TODO: what if the element is dropped? */ | ||||
| 
 | ||||
|                         if (i + n > tbl_inst->cur_size) { | ||||
|                             /* TODO: verify warning content */ | ||||
|                         if (offset_len_out_of_bounds(i, n, | ||||
|                                                      tbl_inst->cur_size)) { | ||||
|                             wasm_set_exception(module, | ||||
|                                                "out of bounds table access"); | ||||
|                             goto got_exception; | ||||
|  |  | |||
|  | @ -3078,7 +3078,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, | |||
|                     case WASM_OP_TABLE_INIT: | ||||
|                     { | ||||
|                         uint32 tbl_idx, elem_idx; | ||||
|                         uint64 n, s, d; | ||||
|                         uint32 n, s, d; | ||||
|                         WASMTableInstance *tbl_inst; | ||||
| 
 | ||||
|                         elem_idx = read_uint32(frame_ip); | ||||
|  | @ -3093,18 +3093,21 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, | |||
|                         s = (uint32)POP_I32(); | ||||
|                         d = (uint32)POP_I32(); | ||||
| 
 | ||||
|                         if (!n) { | ||||
|                             break; | ||||
|                         } | ||||
| 
 | ||||
|                         if (n + s > module->module->table_segments[elem_idx] | ||||
|                                         .function_count | ||||
|                             || d + n > tbl_inst->cur_size) { | ||||
|                         if (offset_len_out_of_bounds( | ||||
|                                 s, n, | ||||
|                                 module->module->table_segments[elem_idx] | ||||
|                                     .function_count) | ||||
|                             || offset_len_out_of_bounds(d, n, | ||||
|                                                         tbl_inst->cur_size)) { | ||||
|                             wasm_set_exception(module, | ||||
|                                                "out of bounds table access"); | ||||
|                             goto got_exception; | ||||
|                         } | ||||
| 
 | ||||
|                         if (!n) { | ||||
|                             break; | ||||
|                         } | ||||
| 
 | ||||
|                         if (module->module->table_segments[elem_idx] | ||||
|                                 .is_dropped) { | ||||
|                             wasm_set_exception(module, | ||||
|  | @ -3143,7 +3146,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, | |||
|                     case WASM_OP_TABLE_COPY: | ||||
|                     { | ||||
|                         uint32 src_tbl_idx, dst_tbl_idx; | ||||
|                         uint64 n, s, d; | ||||
|                         uint32 n, s, d; | ||||
|                         WASMTableInstance *src_tbl_inst, *dst_tbl_inst; | ||||
| 
 | ||||
|                         dst_tbl_idx = read_uint32(frame_ip); | ||||
|  | @ -3160,8 +3163,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, | |||
|                         s = (uint32)POP_I32(); | ||||
|                         d = (uint32)POP_I32(); | ||||
| 
 | ||||
|                         if (d + n > dst_tbl_inst->cur_size | ||||
|                             || s + n > src_tbl_inst->cur_size) { | ||||
|                         if (offset_len_out_of_bounds(d, n, | ||||
|                                                      dst_tbl_inst->cur_size) | ||||
|                             || offset_len_out_of_bounds( | ||||
|                                 s, n, src_tbl_inst->cur_size)) { | ||||
|                             wasm_set_exception(module, | ||||
|                                                "out of bounds table access"); | ||||
|                             goto got_exception; | ||||
|  | @ -3232,7 +3237,8 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, | |||
|                         fill_val = POP_I32(); | ||||
|                         i = POP_I32(); | ||||
| 
 | ||||
|                         if (i + n > tbl_inst->cur_size) { | ||||
|                         if (offset_len_out_of_bounds(i, n, | ||||
|                                                      tbl_inst->cur_size)) { | ||||
|                             wasm_set_exception(module, | ||||
|                                                "out of bounds table access"); | ||||
|                             goto got_exception; | ||||
|  |  | |||
|  | @ -3301,13 +3301,13 @@ llvm_jit_table_init(WASMModuleInstance *module_inst, uint32 tbl_idx, | |||
|     bh_assert(tbl_inst); | ||||
|     bh_assert(tbl_seg); | ||||
| 
 | ||||
|     if (!length) { | ||||
|     if (offset_len_out_of_bounds(src_offset, length, tbl_seg->function_count) | ||||
|         || offset_len_out_of_bounds(dst_offset, length, tbl_inst->cur_size)) { | ||||
|         jit_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS); | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     if (length + src_offset > tbl_seg->function_count | ||||
|         || dst_offset + length > tbl_inst->cur_size) { | ||||
|         jit_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS); | ||||
|     if (!length) { | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|  | @ -3349,8 +3349,9 @@ llvm_jit_table_copy(WASMModuleInstance *module_inst, uint32 src_tbl_idx, | |||
|     bh_assert(src_tbl_inst); | ||||
|     bh_assert(dst_tbl_inst); | ||||
| 
 | ||||
|     if ((uint64)dst_offset + length > dst_tbl_inst->cur_size | ||||
|         || (uint64)src_offset + length > src_tbl_inst->cur_size) { | ||||
|     if (offset_len_out_of_bounds(dst_offset, length, dst_tbl_inst->cur_size) | ||||
|         || offset_len_out_of_bounds(src_offset, length, | ||||
|                                     src_tbl_inst->cur_size)) { | ||||
|         jit_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS); | ||||
|         return; | ||||
|     } | ||||
|  | @ -3382,7 +3383,7 @@ llvm_jit_table_fill(WASMModuleInstance *module_inst, uint32 tbl_idx, | |||
|     tbl_inst = wasm_get_table_inst(module_inst, tbl_idx); | ||||
|     bh_assert(tbl_inst); | ||||
| 
 | ||||
|     if (data_offset + length > tbl_inst->cur_size) { | ||||
|     if (offset_len_out_of_bounds(data_offset, length, tbl_inst->cur_size)) { | ||||
|         jit_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS); | ||||
|         return; | ||||
|     } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Wenyong Huang
						Wenyong Huang