wabt
wabt copied to clipboard
wasm-objdump cannot handle prefixed instructions with non-canonical leb128 opcodes
Uploaded a test case:
$ wasm-objdump -d wasm-objdump-fails.txt
clusterfuzz-testcase-minimized-v8_wasm_async_fuzzer-5664681130524672: file format wasm 0x1
Code Disassembly:
00002d func[0] <main>:
00002e: 03 7e | local[0..2] type=i64
000030: 20 00 | local.get 0
000032: 41 d6 49 | i32.const 4294960342
000035: 02 7f | block i32
000037: 41 fe 20 | i32.const 4222
00003a: 0c 00 | br 0
00003c: 68 | i32.ctz
00003d: fc 0e 00 00 | table.copy 0 0
000041: 0b | end
000042: 20 00 | local.get 0
000044: 68 | i32.ctz
000045: fc 10 00 | table.size 0
000048: 68 | i32.ctz
warning: 0x4d missing opcode callback at 0x4a (0xfc=<invalid>)
wasm2wat works
$ wasm2wat wasm-objdump-fails.txt --enable-all
(module
(type (;0;) (func (result i32)))
(type (;1;) (func (param i32) (result i32)))
(func (;0;) (type 1) (param i32) (result i32)
(local i64 i64 i64)
local.get 0
i32.const -6954
block (result i32) ;; label = @1
i32.const 4222
br 0 (;@1;)
i32.ctz
table.copy
end
local.get 0
i32.ctz
table.size 0
i32.ctz
table.size 0
unreachable
table.set 0)
(table (;0;) 1 9 funcref)
(export "main" (func 0)))
The problematic input is the second table.size 0 instruction, it is encoded as fc 90 80 00 00, the opcode is 4 bytes, the canonical binary should be simply fc 16.
I think this is failing because https://github.com/WebAssembly/wabt/blob/master/src/binary-reader-objdump.cc#L511 calls GetLength, which writes the canonical encoding in https://github.com/WebAssembly/wabt/blob/master/src/opcode.cc#L374 then count the bytes.
Would changing the != to a < at https://github.com/WebAssembly/wabt/blob/master/src/binary-reader-objdump.cc#L511 fix the issue? Any danger in doing this?
Hm, seems like a good fix. It would take care of all cases where opcode.GetLength() under reports.