Skip to content

Commit 313ce8c

Browse files
authored
Fix memory/table segment checks in memory.init/table.init (#3081)
According to the wasm core spec, the checks for the table segments in `table.init` opcode are similar to the checks for `memory.init` opcode: - The size of a passive segment is shrunk to zero after `data.drop` (or `elem.drop`) opcode is executed, and the segment can be used to do `memory.init` (or `table.init`) again - The `memory.init` only traps when `s+n > len(data.data)` or `d+n > len(mem.data)` and `table.init` only traps when `s+n > len(elem.elem)` or `d+n > len(tab.elem)` - The active segment can also be used to do `memory.init` (or `table.init`), while it behaves like a dropped passive segment https://github.com/WebAssembly/bulk-memory-operations/blob/master/proposals/bulk-memory-operations/Overview.md ``` Segments can also be shrunk to size zero by using the following new instructions: - data.drop: discard the data in an data segment - elem.drop: discard the data in an element segment An active segment is equivalent to a passive segment, but with an implicit memory.init followed by a data.drop (or table.init followed by a elem.drop) that is prepended to the module's start function. ``` ps. https://webassembly.github.io/spec/core/bikeshed/#-hrefsyntax-instr-memorymathsfmemoryinitx%E2%91%A0 https://webassembly.github.io/spec/core/bikeshed/#-hrefsyntax-instr-tablemathsftableinitxy%E2%91%A0 #3020
1 parent 6daaf6d commit 313ce8c

File tree

5 files changed

+73
-86
lines changed

5 files changed

+73
-86
lines changed

core/iwasm/aot/aot_runtime.c

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1179,6 +1179,10 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
11791179
"failed to allocate bitmaps");
11801180
goto fail;
11811181
}
1182+
for (i = 0; i < module->mem_init_data_count; i++) {
1183+
if (!module->mem_init_data_list[i]->is_passive)
1184+
bh_bitmap_set_bit(common->data_dropped, i);
1185+
}
11821186
}
11831187
#endif
11841188
#if WASM_ENABLE_REF_TYPES != 0
@@ -1190,6 +1194,10 @@ aot_instantiate(AOTModule *module, AOTModuleInstance *parent,
11901194
"failed to allocate bitmaps");
11911195
goto fail;
11921196
}
1197+
for (i = 0; i < module->table_init_data_count; i++) {
1198+
if (wasm_elem_is_active(module->table_init_data_list[i]->mode))
1199+
bh_bitmap_set_bit(common->elem_dropped, i);
1200+
}
11931201
}
11941202
#endif
11951203

@@ -2621,6 +2629,7 @@ aot_table_init(AOTModuleInstance *module_inst, uint32 tbl_idx,
26212629
{
26222630
AOTTableInstance *tbl_inst;
26232631
AOTTableInitData *tbl_seg;
2632+
uint32 *tbl_seg_elems = NULL, tbl_seg_len = 0;
26242633
const AOTModule *module = (AOTModule *)module_inst->module;
26252634

26262635
tbl_inst = module_inst->tables[tbl_idx];
@@ -2629,32 +2638,28 @@ aot_table_init(AOTModuleInstance *module_inst, uint32 tbl_idx,
26292638
tbl_seg = module->table_init_data_list[tbl_seg_idx];
26302639
bh_assert(tbl_seg);
26312640

2632-
if (offset_len_out_of_bounds(src_offset, length, tbl_seg->func_index_count)
2633-
|| offset_len_out_of_bounds(dst_offset, length, tbl_inst->cur_size)) {
2634-
aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
2635-
return;
2636-
}
2637-
2638-
if (!length) {
2639-
return;
2640-
}
2641-
2642-
if (bh_bitmap_get_bit(
2641+
if (!bh_bitmap_get_bit(
26432642
((AOTModuleInstanceExtra *)module_inst->e)->common.elem_dropped,
26442643
tbl_seg_idx)) {
2644+
/* table segment isn't dropped */
2645+
tbl_seg_elems = tbl_seg->func_indexes;
2646+
tbl_seg_len = tbl_seg->func_index_count;
2647+
}
2648+
2649+
if (offset_len_out_of_bounds(src_offset, length, tbl_seg_len)
2650+
|| offset_len_out_of_bounds(dst_offset, length, tbl_inst->cur_size)) {
26452651
aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
26462652
return;
26472653
}
26482654

2649-
if (!wasm_elem_is_passive(tbl_seg->mode)) {
2650-
aot_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
2655+
if (!length) {
26512656
return;
26522657
}
26532658

26542659
bh_memcpy_s((uint8 *)tbl_inst + offsetof(AOTTableInstance, elems)
26552660
+ dst_offset * sizeof(uint32),
26562661
(tbl_inst->cur_size - dst_offset) * sizeof(uint32),
2657-
tbl_seg->func_indexes + src_offset, length * sizeof(uint32));
2662+
tbl_seg_elems + src_offset, length * sizeof(uint32));
26582663
}
26592664

26602665
void

core/iwasm/fast-jit/fe/jit_emit_table.c

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -88,17 +88,21 @@ jit_compile_op_table_set(JitCompContext *cc, uint32 tbl_idx)
8888
}
8989

9090
static int
91-
wasm_init_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 elem_idx,
91+
wasm_init_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 seg_idx,
9292
uint32 dst_offset, uint32 len, uint32 src_offset)
9393
{
9494
WASMTableInstance *tbl;
9595
uint32 tbl_sz;
96-
WASMTableSeg *elem;
97-
uint32 elem_len;
96+
WASMTableSeg *tbl_seg = inst->module->table_segments + seg_idx;
97+
uint32 *tbl_seg_elems = NULL, tbl_seg_len = 0;
9898

99-
elem = inst->module->table_segments + elem_idx;
100-
elem_len = elem->function_count;
101-
if (offset_len_out_of_bounds(src_offset, len, elem_len))
99+
if (!bh_bitmap_get_bit(inst->e->common.elem_dropped, seg_idx)) {
100+
/* table segment isn't dropped */
101+
tbl_seg_elems = tbl_seg->func_indexes;
102+
tbl_seg_len = tbl_seg->function_count;
103+
}
104+
105+
if (offset_len_out_of_bounds(src_offset, len, tbl_seg_len))
102106
goto out_of_bounds;
103107

104108
tbl = inst->tables[tbl_idx];
@@ -109,17 +113,10 @@ wasm_init_table(WASMModuleInstance *inst, uint32 tbl_idx, uint32 elem_idx,
109113
if (!len)
110114
return 0;
111115

112-
if (bh_bitmap_get_bit(inst->e->common.elem_dropped, elem_idx))
113-
goto out_of_bounds;
114-
115-
if (!wasm_elem_is_passive(inst->module->table_segments[elem_idx].mode))
116-
goto out_of_bounds;
117-
118116
bh_memcpy_s((uint8 *)tbl + offsetof(WASMTableInstance, elems)
119117
+ dst_offset * sizeof(uint32),
120118
(uint32)((tbl_sz - dst_offset) * sizeof(uint32)),
121-
elem->func_indexes + src_offset,
122-
(uint32)(len * sizeof(uint32)));
119+
tbl_seg_elems + src_offset, (uint32)(len * sizeof(uint32)));
123120

124121
return 0;
125122
out_of_bounds:

core/iwasm/interpreter/wasm_interp_classic.c

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3262,6 +3262,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
32623262
uint32 tbl_idx, elem_idx;
32633263
uint32 n, s, d;
32643264
WASMTableInstance *tbl_inst;
3265+
uint32 *tbl_seg_elems = NULL, tbl_seg_len = 0;
32653266

32663267
read_leb_uint32(frame_ip, frame_ip_end, elem_idx);
32673268
bh_assert(elem_idx < module->module->table_seg_count);
@@ -3275,10 +3276,18 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
32753276
s = (uint32)POP_I32();
32763277
d = (uint32)POP_I32();
32773278

3278-
if (offset_len_out_of_bounds(
3279-
s, n,
3279+
if (!bh_bitmap_get_bit(module->e->common.elem_dropped,
3280+
elem_idx)) {
3281+
/* table segment isn't dropped */
3282+
tbl_seg_elems =
32803283
module->module->table_segments[elem_idx]
3281-
.function_count)
3284+
.func_indexes;
3285+
tbl_seg_len =
3286+
module->module->table_segments[elem_idx]
3287+
.function_count;
3288+
}
3289+
3290+
if (offset_len_out_of_bounds(s, n, tbl_seg_len)
32823291
|| offset_len_out_of_bounds(d, n,
32833292
tbl_inst->cur_size)) {
32843293
wasm_set_exception(module,
@@ -3290,30 +3299,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
32903299
break;
32913300
}
32923301

3293-
if (bh_bitmap_get_bit(module->e->common.elem_dropped,
3294-
elem_idx)) {
3295-
wasm_set_exception(module,
3296-
"out of bounds table access");
3297-
goto got_exception;
3298-
}
3299-
3300-
if (!wasm_elem_is_passive(
3301-
module->module->table_segments[elem_idx]
3302-
.mode)) {
3303-
wasm_set_exception(module,
3304-
"out of bounds table access");
3305-
goto got_exception;
3306-
}
3307-
33083302
bh_memcpy_s(
33093303
(uint8 *)tbl_inst
33103304
+ offsetof(WASMTableInstance, elems)
33113305
+ d * sizeof(uint32),
33123306
(uint32)((tbl_inst->cur_size - d) * sizeof(uint32)),
3313-
module->module->table_segments[elem_idx]
3314-
.func_indexes
3315-
+ s,
3316-
(uint32)(n * sizeof(uint32)));
3307+
tbl_seg_elems + s, (uint32)(n * sizeof(uint32)));
33173308

33183309
break;
33193310
}

core/iwasm/interpreter/wasm_interp_fast.c

Lines changed: 13 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3023,7 +3023,6 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
30233023
data = NULL;
30243024
}
30253025
else {
3026-
30273026
seg_len =
30283027
(uint64)module->module->data_segments[segment]
30293028
->data_length;
@@ -3106,6 +3105,7 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
31063105
uint32 tbl_idx, elem_idx;
31073106
uint32 n, s, d;
31083107
WASMTableInstance *tbl_inst;
3108+
uint32 *tbl_seg_elems = NULL, tbl_seg_len = 0;
31093109

31103110
elem_idx = read_uint32(frame_ip);
31113111
bh_assert(elem_idx < module->module->table_seg_count);
@@ -3119,10 +3119,18 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
31193119
s = (uint32)POP_I32();
31203120
d = (uint32)POP_I32();
31213121

3122-
if (offset_len_out_of_bounds(
3123-
s, n,
3122+
if (!bh_bitmap_get_bit(module->e->common.elem_dropped,
3123+
elem_idx)) {
3124+
/* table segment isn't dropped */
3125+
tbl_seg_elems =
3126+
module->module->table_segments[elem_idx]
3127+
.func_indexes;
3128+
tbl_seg_len =
31243129
module->module->table_segments[elem_idx]
3125-
.function_count)
3130+
.function_count;
3131+
}
3132+
3133+
if (offset_len_out_of_bounds(s, n, tbl_seg_len)
31263134
|| offset_len_out_of_bounds(d, n,
31273135
tbl_inst->cur_size)) {
31283136
wasm_set_exception(module,
@@ -3134,30 +3142,12 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
31343142
break;
31353143
}
31363144

3137-
if (bh_bitmap_get_bit(module->e->common.elem_dropped,
3138-
elem_idx)) {
3139-
wasm_set_exception(module,
3140-
"out of bounds table access");
3141-
goto got_exception;
3142-
}
3143-
3144-
if (!wasm_elem_is_passive(
3145-
module->module->table_segments[elem_idx]
3146-
.mode)) {
3147-
wasm_set_exception(module,
3148-
"out of bounds table access");
3149-
goto got_exception;
3150-
}
3151-
31523145
bh_memcpy_s(
31533146
(uint8 *)tbl_inst
31543147
+ offsetof(WASMTableInstance, elems)
31553148
+ d * sizeof(uint32),
31563149
(uint32)((tbl_inst->cur_size - d) * sizeof(uint32)),
3157-
module->module->table_segments[elem_idx]
3158-
.func_indexes
3159-
+ s,
3160-
(uint32)(n * sizeof(uint32)));
3150+
tbl_seg_elems + s, (uint32)(n * sizeof(uint32)));
31613151
break;
31623152
}
31633153
case WASM_OP_ELEM_DROP:

core/iwasm/interpreter/wasm_runtime.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1670,6 +1670,10 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
16701670
"failed to allocate bitmaps");
16711671
goto fail;
16721672
}
1673+
for (i = 0; i < module->data_seg_count; i++) {
1674+
if (!module->data_segments[i]->is_passive)
1675+
bh_bitmap_set_bit(module_inst->e->common.data_dropped, i);
1676+
}
16731677
}
16741678
#endif
16751679
#if WASM_ENABLE_REF_TYPES != 0
@@ -1682,6 +1686,10 @@ wasm_instantiate(WASMModule *module, WASMModuleInstance *parent,
16821686
"failed to allocate bitmaps");
16831687
goto fail;
16841688
}
1689+
for (i = 0; i < module->table_seg_count; i++) {
1690+
if (wasm_elem_is_active(module->table_segments[i].mode))
1691+
bh_bitmap_set_bit(module_inst->e->common.elem_dropped, i);
1692+
}
16851693
}
16861694
#endif
16871695

@@ -3278,6 +3286,7 @@ llvm_jit_table_init(WASMModuleInstance *module_inst, uint32 tbl_idx,
32783286
{
32793287
WASMTableInstance *tbl_inst;
32803288
WASMTableSeg *tbl_seg;
3289+
uint32 *tbl_seg_elems = NULL, tbl_seg_len = 0;
32813290

32823291
bh_assert(module_inst->module_type == Wasm_Module_Bytecode);
32833292

@@ -3287,31 +3296,26 @@ llvm_jit_table_init(WASMModuleInstance *module_inst, uint32 tbl_idx,
32873296
bh_assert(tbl_inst);
32883297
bh_assert(tbl_seg);
32893298

3290-
if (offset_len_out_of_bounds(src_offset, length, tbl_seg->function_count)
3291-
|| offset_len_out_of_bounds(dst_offset, length, tbl_inst->cur_size)) {
3292-
jit_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
3293-
return;
3294-
}
3295-
3296-
if (!length) {
3297-
return;
3299+
if (!bh_bitmap_get_bit(module_inst->e->common.elem_dropped, tbl_seg_idx)) {
3300+
/* table segment isn't dropped */
3301+
tbl_seg_elems = tbl_seg->func_indexes;
3302+
tbl_seg_len = tbl_seg->function_count;
32983303
}
32993304

3300-
if (bh_bitmap_get_bit(module_inst->e->common.elem_dropped, tbl_seg_idx)) {
3305+
if (offset_len_out_of_bounds(src_offset, length, tbl_seg_len)
3306+
|| offset_len_out_of_bounds(dst_offset, length, tbl_inst->cur_size)) {
33013307
jit_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
33023308
return;
33033309
}
33043310

3305-
if (!wasm_elem_is_passive(tbl_seg->mode)) {
3306-
jit_set_exception_with_id(module_inst, EXCE_OUT_OF_BOUNDS_TABLE_ACCESS);
3311+
if (!length) {
33073312
return;
33083313
}
33093314

33103315
bh_memcpy_s((uint8 *)tbl_inst + offsetof(WASMTableInstance, elems)
33113316
+ dst_offset * sizeof(uint32),
33123317
(uint32)sizeof(uint32) * (tbl_inst->cur_size - dst_offset),
3313-
tbl_seg->func_indexes + src_offset,
3314-
(uint32)(length * sizeof(uint32)));
3318+
tbl_seg_elems + src_offset, (uint32)(length * sizeof(uint32)));
33153319
}
33163320

33173321
void

0 commit comments

Comments
 (0)