Better handling of invalid/corrupted wasm files ##bin

This commit is contained in:
Dennis Goodlett 2022-06-15 15:45:06 -04:00 committed by pancake
parent 27bc692b91
commit ead6d82efa
2 changed files with 20 additions and 7 deletions

View File

@ -413,7 +413,6 @@ static void wasm_custom_name_free(RBinWasmCustomNameEntry *cust) {
// Parsing
static inline RPVector *parse_vec(RBinWasmObj *bin, ut64 bound, ParseEntryFcn parse_entry, RPVectorFree free_entry) {
RBuffer *buf = bin->buf;
ut64 start = r_buf_tell (buf);
ut32 count;
if (!consume_u32_r (buf, bound, &count)) {
@ -425,6 +424,7 @@ static inline RPVector *parse_vec(RBinWasmObj *bin, ut64 bound, ParseEntryFcn pa
r_pvector_reserve (vec, count);
ut32 i;
for (i = 0; i < count; i++) {
ut64 start = r_buf_tell (buf);
void *e = parse_entry (bin, bound, i);
if (!e || !r_pvector_push (vec, e)) {
eprintf ("[wasm] Failed to parse entry %u/%u of vec at 0x%" PFMT64x "\n", i, count, start);
@ -598,6 +598,8 @@ static RBinWasmCodeEntry *parse_code_entry(RBinWasmObj *bin, ut64 bound, ut32 in
ut8 end;
r_buf_read (b, &end, 1);
if (end != R_BIN_WASM_END_OF_CODE) {
eprintf ("[wasm] Code entry at starting at 0x%" PFMT64x " has ending byte 0x%x at 0x%x, should be 0x%x\n",
ptr->file_offset, end, r_buf_tell (b) - 1, R_BIN_WASM_END_OF_CODE);
goto beach;
}
return ptr;
@ -984,9 +986,6 @@ RList *r_bin_wasm_get_sections(RBinWasmObj *bin) {
// free (ptr);
// continue;
}
if (r_buf_tell (b) + (ut64)ptr->size - 1 > bound) {
goto beach;
}
ptr->offset = r_buf_tell (b);
switch (ptr->id) {
case R_BIN_WASM_SECTION_CUSTOM:
@ -1055,6 +1054,12 @@ RList *r_bin_wasm_get_sections(RBinWasmObj *bin) {
r_buf_seek (b, ptr->size - 1, R_BUF_CUR);
continue;
}
if (ptr->offset + (ut64)ptr->size - 1 > bound) {
// TODO: Better error handling here
ut32 diff = ptr->size - (bound + 1 - ptr->offset);
eprintf ("[wasm] Artificially reducing size of section %s by 0x%x bytes so it fits in the file\n", ptr->name, diff);
ptr->size -= diff;
}
ptr->payload_data = r_buf_tell (b);
ptr->payload_len = ptr->size - (ptr->payload_data - ptr->offset);
if (ptr->payload_len > ptr->size) {

View File

@ -10,6 +10,14 @@
#include "wasm/wasm.h"
#include "../format/wasm/wasm.h"
static inline void *vector_at(RPVector *vec, ut64 n) {
// If the file is corrupted, the section may not have as many entries as it should
if (n < r_pvector_len (vec)) {
return r_pvector_at (vec, n);
}
return NULL;
}
static bool check_buffer(RBinFile *bf, RBuffer *rbuf) {
ut8 buf[4] = {0};
return rbuf && r_buf_read_at (rbuf, 0, buf, 4) == 4 && !memcmp (buf, R_BIN_WASM_MAGIC_BYTES, 4);
@ -52,7 +60,7 @@ static inline RBinWasmExportEntry *find_export(RPVector *exports, ut8 kind, ut32
}
struct search_fields sf = { .kind = kind, .index = index };
int n = r_pvector_bsearch (exports, (void *)&sf, _export_finder);
return n >= 0? r_pvector_at (exports, n): NULL;
return n >= 0? vector_at (exports, n): NULL;
}
static bool load_buffer(RBinFile *bf, void **bin_obj, RBuffer *buf, ut64 loadaddr, Sdb *sdb) {
@ -85,7 +93,7 @@ static RList *entries(RBinFile *bf) {
if (!addr) {
RPVector *codes = r_bin_wasm_get_codes (bin);
if (codes) {
RBinWasmCodeEntry *func = r_pvector_at (codes, 0);
RBinWasmCodeEntry *func = vector_at (codes, 0);
if (func) {
addr = func->code;
}
@ -337,7 +345,7 @@ static int get_fcn_offset_from_id(RBinFile *bf, int fcn_idx) {
RBinWasmObj *bin = bf->o->bin_obj;
RPVector *codes = r_bin_wasm_get_codes (bin);
if (codes) {
RBinWasmCodeEntry *func = r_pvector_at (codes, fcn_idx);
RBinWasmCodeEntry *func = vector_at (codes, fcn_idx);
if (func) {
return func->code;
}