Avoids leak in wasm details#1372
Conversation
|
this is nice, but i am wondering if we can fix it differently by having operands as a fixed size array, @Spikel? |
|
We have some line There seem to me to be other problems with this code (lack of check before allocating much arbitrary memory size) |
| cs_wasm wasm; ///< Web Assembly architecture | ||
| cs_mos65xx mos65xx; ///< MOS65XX architecture (including MOS6502) | ||
| }; | ||
| cs_arch arch; ///Used architecture (for architecture-specific free) |
There was a problem hiding this comment.
this does not look good, but sounds like we cannot avoid adding this field?
another solution is to have a new csh argument for cs_free()
There was a problem hiding this comment.
Indeed.
As a recap, I see three solutions :
- this patch (but more memory consumption)
- changing
cs_freeprototype (but changing interface is painful for people using this project) - changing how WASM handles this "switch" jump table (but I am not sure if this relevant for WASM)
Which is the best ?
There was a problem hiding this comment.
yes we try best to avoid breaking compatibility, but in this case i think that is still better than having the extra arch field in cs_insn. finally, it was a mistake not to have csh arg in every API. we may afford changing API in the version 5, which will have major update in all archs.
if there is upper limit for brtable, we can avoid this mess by having fixed size array for operands. lets see what @Spikel has to say when he is back.
|
So, oss-fuzz indeed found the bug for arbitrary size memory allocation : So I pushed another commit adding a safety check... |
|
nice work! i think @Spikel will get back from holidays next week to look at this bug. |
|
oh now this PR mixes with an old commit, from arch/TMS320C64x/TMS320C64xMapping.c. |
5641768 to
c3df800
Compare
|
I rebased to remove this other commit |
|
Another way to avoid breaking compatibility is to have a new API, lets say cs_free_ex(), which accepts csh as its first param, and promote it as future replacement for cs_free() in next few version. |
|
Newest version changes how WASM handles this switch table, this seems better for #1381 as well |
Extending cs_detail in capstone.h
This reverts commit 03f822b.
dcd8232 to
14e068f
Compare
|
so the main change is that operands[] now has upper limit of 2? |
|
Yes :
|
I want to try another solution, before I malloc the memory, I do some basic check, to make sure there are enough bytes to satisfied this length. then I will do malloc, if not, I will return false. what's more, I do not malloc such large memory space at one time, first I will malloc 1/4 of the needed space, and realloc twice. the first malloc make sure the space is the same as the binary size itself, If we have a big binary we also need a big memory space. I think it is reasonable. |
| } | ||
|
|
||
| data = data + ((code[i] & 0x7f) << (i * 7)); | ||
| data = data + (((uint64_t) code[i] & 0x7f) << (i * 7)); |
There was a problem hiding this comment.
this should fit in a separate pull req, so i can merge it independently?
There was a problem hiding this comment.
indeed, do you want me to submit a separate pull request ?
There was a problem hiding this comment.
or if @SpikeI agree with every changes here, i can merge all of them, without needing you to create a new PR.
|
@Spikel this will not solve yet the overlong instruction printing from #1381 : capstone limits it to 512 bytes, and so we cannot print a WASM brtable with some hundreds of targets... For the safety checks, you can look at 6e53ff1 This proposed solution looks to me more like @aquynh what do you think ? |
|
Wasm is really special, because it has this br_table instruction, that can be arbitrary long, thus does fit into the existing model. @catenacyber i think your approach is reasonable. @SpikeI may come up with a similar fix. |
There was a problem hiding this comment.
@Spikel this will not solve yet the overlong instruction printing from #1381 : capstone limits it to 512 bytes, and so we cannot print a WASM brtable with some hundreds of targets...
For the safety checks, you can look at 6e53ff1
This proposed solution looks to me more like
switchinstruction in other architectures : the jump table's address is given and the user has to decode all the targets himself. The difference with other architectures is that with WASM, targets are encoded with variable length...@aquynh what do you think ?
I see, you are right. Its my fault to leave many memory mistakes.
the safety check is good, and the table we can not print. you are right.
the only inconvenient thing is that user should read varuint32 themself?
| } | ||
|
|
||
| MI->wasm_data.brtable.target[i] = get_varuint32(code + tmp_len, code_len - tmp_len, &var_len); | ||
| get_varuint32(code + tmp_len, code_len - tmp_len, &var_len); |
There was a problem hiding this comment.
why we do not keep this data?
@catenacyber @aquynh |
|
merged, thanks! |
|
Thanks @SpikeI for agreeing and congratulations for your work :-) |
Extending cs_detail in capstone.h
Another way would have been to change the prototype of
cs_freeThis change seemed to me less disruptive for existing programs (no need to change the code using capstone, just a bit more memory consumption)
This was found by oss-fuzz :
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=12952
(And this likely hides other bugs from fuzzing)