Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix multiple vulnerabilities #2977

Merged
merged 20 commits into from
Aug 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions librz/analysis/dwarf_process.c
Original file line number Diff line number Diff line change
Expand Up @@ -1239,13 +1239,15 @@ static st32 parse_function_args_and_vars(Context *ctx, ut64 idx, RzStrBuf *args,
const RzBinDwarfAttrValue *val = &child_die->attr_values[i];
switch (val->attr_name) {
case DW_AT_name:
if (!get_linkage_name || !has_linkage_name) {
if ((!get_linkage_name || !has_linkage_name) && val->kind == DW_AT_KIND_STRING) {
name = val->string.content;
}
break;
case DW_AT_linkage_name:
case DW_AT_MIPS_linkage_name:
name = val->string.content;
if (val->kind == DW_AT_KIND_STRING) {
name = val->string.content;
}
has_linkage_name = true;
break;
case DW_AT_type:
Expand Down
10 changes: 7 additions & 3 deletions librz/bin/bin.c
Original file line number Diff line number Diff line change
Expand Up @@ -1382,8 +1382,8 @@ RZ_API RZ_OWN char *rz_bin_demangle(RZ_NULLABLE RzBinFile *bf, RZ_NULLABLE const
if (!found) {
lib = NULL;
}
size_t len = strlen(bin->file);
if (!rz_str_ncasecmp(symbol, bin->file, len)) {
size_t len = bin ? strlen(bin->file) : 0;
if (bin && len > 0 && !rz_str_ncasecmp(symbol, bin->file, len)) {
lib = bin->file;
symbol += len;
if (*symbol == '_') {
Expand Down Expand Up @@ -1432,7 +1432,11 @@ RZ_API RZ_OWN char *rz_bin_demangle(RZ_NULLABLE RzBinFile *bf, RZ_NULLABLE const
case RZ_BIN_LANGUAGE_RUST: demangled = NULL; break;
case RZ_BIN_LANGUAGE_CXX: demangled = NULL; break;
#endif
default: rz_demangler_resolve(bin->demangler, symbol, language, &demangled);
default:
if (bin) {
rz_demangler_resolve(bin->demangler, symbol, language, &demangled);
}
break;
}
if (libs && demangled && lib) {
char *d = rz_str_newf("%s_%s", lib, demangled);
Expand Down
10 changes: 5 additions & 5 deletions librz/bin/dwarf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1215,7 +1215,7 @@ static int init_die(RzBinDwarfDie *die, ut64 abbr_code, ut64 attr_count) {
return -1;
}
if (attr_count) {
die->attr_values = calloc(sizeof(RzBinDwarfAttrValue), attr_count);
die->attr_values = RZ_NEWS0(RzBinDwarfAttrValue, attr_count);
if (!die->attr_values) {
return -1;
}
Expand Down Expand Up @@ -1725,7 +1725,7 @@ static const ut8 *parse_die(const ut8 *buf, const ut8 *buf_end, RzBinDwarfDebugI
const char *comp_dir = NULL;
ut64 line_info_offset = UT64_MAX;
if (abbrev->count) {
for (i = 0; i < abbrev->count - 1; i++) {
for (i = 0; i < abbrev->count - 1 && die->count < die->capacity; i++) {
memset(&die->attr_values[i], 0, sizeof(die->attr_values[i]));

buf = parse_attr_value(buf, buf_end - buf, &abbrev->defs[i],
Expand Down Expand Up @@ -1774,11 +1774,11 @@ static const ut8 *parse_die(const ut8 *buf, const ut8 *buf_end, RzBinDwarfDebugI
* @return const ut8* Update buffer
*/
static const ut8 *parse_comp_unit(RzBinDwarfDebugInfo *info, const ut8 *buf_start,
RzBinDwarfCompUnit *unit, const RzBinDwarfDebugAbbrev *abbrevs,
size_t buf_len, RzBinDwarfCompUnit *unit, const RzBinDwarfDebugAbbrev *abbrevs,
size_t first_abbr_idx, const ut8 *debug_str, size_t debug_str_len, bool big_endian) {

const ut8 *buf = buf_start;
const ut8 *buf_end = buf_start + unit->hdr.length - unit->hdr.header_size;
const ut8 *buf_end = buf_start + RZ_MIN(buf_len, unit->hdr.length - unit->hdr.header_size);

while (buf && buf < buf_end && buf >= buf_start) {
if (unit->count && unit->capacity == unit->count) {
Expand Down Expand Up @@ -1952,7 +1952,7 @@ static RzBinDwarfDebugInfo *parse_info_raw(RzBinDwarfDebugAbbrev *da,
// They point to the same array object, so should be def. behaviour
size_t first_abbr_idx = abbrev_start - da->decls;

buf = parse_comp_unit(info, buf, unit, da, first_abbr_idx, debug_str, debug_str_len, big_endian);
buf = parse_comp_unit(info, buf, buf_end - buf, unit, da, first_abbr_idx, debug_str, debug_str_len, big_endian);

if (!buf) {
goto cleanup;
Expand Down
17 changes: 14 additions & 3 deletions librz/bin/format/dex/dex.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ static DexString *dex_string_new(RzBuffer *buf, ut64 offset, st64 *pread) {
DexString *string = NULL;

read = rz_buf_uleb128(buf, &size);
if (UT64_ADD_OVFCHK(size, 1)) {
return NULL;
}

data = malloc(size + 1);
if (!data || rz_buf_read(buf, (ut8 *)data, size) != size) {
free(data);
Expand Down Expand Up @@ -816,6 +820,9 @@ static char *dex_resolve_proto_id(RzBinDex *dex, const char *name, ut32 proto_id
rz_strbuf_append(sb, "(");
for (ut32 i = 0; i < proto_id->type_list_size; ++i) {
ut32 type_idx = proto_id->type_list[i];
if (type_idx >= dex->type_ids_size) {
continue;
}

const DexString *param = dex_resolve_string_id_native(dex, dex->types[type_idx]);
if (!param) {
Expand Down Expand Up @@ -902,7 +909,9 @@ static char *dex_resolve_library(const char *library) {
}
char *demangled = strdup(library + 1);
rz_str_replace_ch(demangled, '/', '.', 1);
demangled[strlen(demangled) - 1] = 0;
if (RZ_STR_ISNOTEMPTY(demangled)) {
demangled[strlen(demangled) - 1] = 0;
}
return demangled;
}

Expand Down Expand Up @@ -1429,7 +1438,8 @@ RZ_API RZ_OWN RzList /*<RzBinImport *>*/ *rz_bin_dex_imports(RZ_NONNULL RzBinDex
}

char *object = dex_resolve_type_id(dex, field_id->class_idx);
if (!object) {
if (RZ_STR_ISEMPTY(object)) {
free(object);
free(import);
break;
}
Expand Down Expand Up @@ -1476,7 +1486,8 @@ RZ_API RZ_OWN RzList /*<RzBinImport *>*/ *rz_bin_dex_imports(RZ_NONNULL RzBinDex
}

char *object = dex_resolve_type_id(dex, method_id->class_idx);
if (!object) {
if (RZ_STR_ISEMPTY(object)) {
free(object);
rz_bin_import_free(import);
break;
}
Expand Down
17 changes: 5 additions & 12 deletions librz/bin/format/mach0/coresymbolication.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,21 +117,14 @@ RZ_API ut64 rz_coresym_cache_element_pa2va(RzCoreSymCacheElement *element, ut64

static char *str_dup_safe(const ut8 *b, const ut8 *str, const ut8 *end) {
if (str >= b && str < end) {
int len = rz_str_nlen((const char *)str, end - str);
if (len) {
return rz_str_ndup((const char *)str, len);
}
return rz_str_ndup((const char *)str, end - str);
}
return NULL;
}

static char *str_dup_safe_fixed(const ut8 *b, const ut8 *str, ut64 len, const ut8 *end) {
static char *str_ndup_safe(const ut8 *b, const ut8 *str, ut64 len, const ut8 *end) {
wargio marked this conversation as resolved.
Show resolved Hide resolved
if (str >= b && str + len < end) {
char *result = calloc(1, len + 1);
if (result) {
rz_str_ncpy(result, (const char *)str, len);
return result;
}
return rz_str_ndup((const char *)str, len);
}
return NULL;
}
Expand Down Expand Up @@ -206,15 +199,15 @@ RZ_API RzCoreSymCacheElement *rz_coresym_cache_element_new(RzBinFile *bf, RzBuff
RzCoreSymCacheElementSegment *seg = &result->segments[i];
seg->paddr = seg->vaddr = rz_read_le64(cursor);
cursor += 8;
if (cursor >= end) {
if ((cursor + 8) >= end) {
goto beach;
}
seg->size = seg->vsize = rz_read_le64(cursor);
cursor += 8;
if (cursor >= end) {
goto beach;
}
seg->name = str_dup_safe_fixed(b, cursor, 16, end);
seg->name = str_ndup_safe(b, cursor, 16, end);
cursor += 16;
if (!seg->name) {
goto beach;
Expand Down
4 changes: 3 additions & 1 deletion librz/bin/format/mach0/dyldcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ RZ_API objc_cache_opt_info *rz_dyldcache_get_objc_opt_info(RzBinFile *bf, RzDyld
RzListIter *iter;
RzDyldBinImage *bin;
rz_list_foreach (cache->bins, iter, bin) {
if (strcmp(bin->file, "lib/libobjc.A.dylib")) {
if (!bin->file || strcmp(bin->file, "lib/libobjc.A.dylib")) {
continue;
}

Expand Down Expand Up @@ -626,6 +626,8 @@ static RzList *create_cache_bins(RzDyldCache *cache) {
} else {
bin->file = strdup(file);
}
} else {
bin->file = rz_str_newf("unknown_image_%08" PFMT64x, symbols_off);
}
rz_list_append(bins, bin);
break;
Expand Down
9 changes: 5 additions & 4 deletions librz/bin/format/mach0/mach0.c
Original file line number Diff line number Diff line change
Expand Up @@ -1514,8 +1514,9 @@ static bool parse_chained_fixups(struct MACH0_(obj_t) * bin, ut32 offset, ut32 s
return false;
}
if (cur_seg->page_count > 0) {
ut16 *page_start = malloc(sizeof(ut16) * cur_seg->page_count);
ut16 *page_start = RZ_NEWS0(ut16, cur_seg->page_count);
if (!page_start) {
cur_seg->page_count = 0;
return false;
}
if (rz_buf_fread_at(bin->b, starts_at + seg_off + 22, (ut8 *)page_start, "s", cur_seg->page_count) != cur_seg->page_count * 2) {
Expand Down Expand Up @@ -1597,8 +1598,9 @@ static bool reconstruct_chained_fixup(struct MACH0_(obj_t) * bin) {
cur_seg->page_size = ps;
cur_seg->page_count = ((bin->segs[seg_idx].vmsize + (ps - 1)) & ~(ps - 1)) / ps;
if (cur_seg->page_count > 0) {
cur_seg->page_start = malloc(sizeof(ut16) * cur_seg->page_count);
cur_seg->page_start = RZ_NEWS0(ut16, cur_seg->page_count);
if (!cur_seg->page_start) {
cur_seg->page_count = 0;
break;
}
memset(cur_seg->page_start, 0xff, sizeof(ut16) * cur_seg->page_count);
Expand All @@ -1607,8 +1609,7 @@ static bool reconstruct_chained_fixup(struct MACH0_(obj_t) * bin) {
}
if (cur_seg) {
ut32 page_index = (ut32)(seg_off / ps);
size_t maxsize = cur_seg->page_count * sizeof(ut16);
if (page_index < maxsize) {
if (page_index < cur_seg->page_count) {
cur_seg->page_start[page_index] = seg_off & 0xfff;
}
}
Expand Down
15 changes: 8 additions & 7 deletions librz/bin/format/mach0/mach0_rebase.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,25 @@
RZ_API void MACH0_(rebase_buffer)(struct MACH0_(obj_t) * obj, ut64 off, ut8 *buf, ut64 count) {
rz_return_if_fail(obj && buf);
ut64 eob = off + count;
int nsegs_to_rebase = RZ_MIN(obj->nchained_starts, obj->nsegs);
ut64 nsegs_to_rebase = RZ_MIN(obj->nchained_starts, obj->nsegs);
for (int i = 0; i < nsegs_to_rebase; i++) {
if (!obj->chained_starts[i]) {
continue;
}
ut64 page_size = obj->chained_starts[i]->page_size;
struct rz_dyld_chained_starts_in_segment *segment = obj->chained_starts[i];
ut64 page_size = segment->page_size;
ut64 start = obj->segs[i].fileoff;
ut64 end = start + obj->segs[i].filesize;
if (end < off || start > eob) {
if (end < off || start > eob || page_size < 1) {
continue;
}
ut64 page_idx = (RZ_MAX(start, off) - start) / page_size;
ut64 page_end_idx = (RZ_MIN(eob, end) - start) / page_size;
for (; page_idx <= page_end_idx; page_idx++) {
if (page_idx >= obj->chained_starts[i]->page_count) {
if (!segment->page_start || page_idx >= segment->page_count) {
break;
}
ut16 page_start = obj->chained_starts[i]->page_start[page_idx];
ut16 page_start = segment->page_start[page_idx];
if (page_start == DYLD_CHAINED_PTR_START_NONE) {
continue;
}
Expand All @@ -56,7 +57,7 @@ RZ_API void MACH0_(rebase_buffer)(struct MACH0_(obj_t) * obj, ut64 off, ut8 *buf
ut64 ptr_value = raw_ptr;
ut64 delta;
ut64 stride = 8;
switch (obj->chained_starts[i]->pointer_format) {
switch (segment->pointer_format) {
case DYLD_CHAINED_PTR_ARM64E: {
bool is_bind = IS_PTR_BIND(raw_ptr);
if (is_auth && is_bind) {
Expand Down Expand Up @@ -134,7 +135,7 @@ RZ_API void MACH0_(rebase_buffer)(struct MACH0_(obj_t) * obj, ut64 off, ut8 *buf
}
default:
RZ_LOG_WARN("Unsupported Mach-O pointer format: %u at paddr 0x%" PFMT64x "\n",
obj->chained_starts[i]->pointer_format, cursor);
segment->pointer_format, cursor);
goto break_it_all;
}
ut64 in_buf = cursor - off;
Expand Down
50 changes: 25 additions & 25 deletions librz/bin/format/mdmp/mdmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -76,22 +76,26 @@ ut32 rz_bin_mdmp_get_perm(struct rz_bin_mdmp_obj *obj, ut64 vaddr) {
}
}

static void rz_bin_mdmp_free_pe32_bin(void *pe_bin_) {
struct Pe32_rz_bin_mdmp_pe_bin *pe_bin = pe_bin_;
if (pe_bin) {
static void rz_bin_mdmp_free_pe32_bin(struct Pe32_rz_bin_mdmp_pe_bin *pe_bin) {
if (!pe_bin) {
return;
}
if (pe_bin->bin) {
sdb_free(pe_bin->bin->kv);
Pe32_rz_bin_pe_free(pe_bin->bin);
RZ_FREE(pe_bin);
}
free(pe_bin);
}

static void rz_bin_mdmp_free_pe64_bin(void *pe_bin_) {
struct Pe64_rz_bin_mdmp_pe_bin *pe_bin = pe_bin_;
if (pe_bin) {
static void rz_bin_mdmp_free_pe64_bin(struct Pe64_rz_bin_mdmp_pe_bin *pe_bin) {
if (!pe_bin) {
return;
}
if (pe_bin->bin) {
sdb_free(pe_bin->bin->kv);
Pe64_rz_bin_pe_free(pe_bin->bin);
RZ_FREE(pe_bin);
}
free(pe_bin);
}

void rz_bin_mdmp_free(struct rz_bin_mdmp_obj *obj) {
Expand Down Expand Up @@ -1387,29 +1391,25 @@ static int rz_bin_mdmp_init(struct rz_bin_mdmp_obj *obj) {
}

struct rz_bin_mdmp_obj *rz_bin_mdmp_new_buf(RzBuffer *buf) {
bool fail = false;
struct rz_bin_mdmp_obj *obj = RZ_NEW0(struct rz_bin_mdmp_obj);
if (!obj) {
return NULL;
}
obj->kv = sdb_new0();
obj->size = (ut32)rz_buf_size(buf);

fail |= (!(obj->streams.ex_threads = rz_list_new()));
fail |= (!(obj->streams.memories = rz_list_newf((RzListFree)free)));
fail |= (!(obj->streams.memories64.memories = rz_list_new()));
fail |= (!(obj->streams.memory_infos = rz_list_newf((RzListFree)free)));
fail |= (!(obj->streams.modules = rz_list_newf((RzListFree)free)));
fail |= (!(obj->streams.operations = rz_list_newf((RzListFree)free)));
fail |= (!(obj->streams.thread_infos = rz_list_newf((RzListFree)free)));
fail |= (!(obj->streams.token_infos = rz_list_newf((RzListFree)free)));
fail |= (!(obj->streams.threads = rz_list_new()));
fail |= (!(obj->streams.unloaded_modules = rz_list_newf((RzListFree)free)));

fail |= (!(obj->pe32_bins = rz_list_newf(rz_bin_mdmp_free_pe32_bin)));
fail |= (!(obj->pe64_bins = rz_list_newf(rz_bin_mdmp_free_pe64_bin)));

if (fail) {
if (!obj->kv ||
!(obj->streams.ex_threads = rz_list_new()) ||
!(obj->streams.memories = rz_list_newf((RzListFree)free)) ||
!(obj->streams.memories64.memories = rz_list_new()) ||
!(obj->streams.memory_infos = rz_list_newf((RzListFree)free)) ||
!(obj->streams.modules = rz_list_newf((RzListFree)free)) ||
!(obj->streams.operations = rz_list_newf((RzListFree)free)) ||
!(obj->streams.thread_infos = rz_list_newf((RzListFree)free)) ||
!(obj->streams.token_infos = rz_list_newf((RzListFree)free)) ||
!(obj->streams.threads = rz_list_new()) ||
!(obj->streams.unloaded_modules = rz_list_newf((RzListFree)free)) ||
!(obj->pe32_bins = rz_list_newf((RzListFree)rz_bin_mdmp_free_pe32_bin)) ||
!(obj->pe64_bins = rz_list_newf((RzListFree)rz_bin_mdmp_free_pe64_bin))) {
rz_bin_mdmp_free(obj);
return NULL;
}
Expand Down
23 changes: 16 additions & 7 deletions librz/bin/format/ne/ne.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,26 +438,35 @@ RzList *rz_bin_ne_get_entrypoints(rz_bin_ne_obj_t *bin) {
break;
} else if (bundle_type == 0xFF) { // Moveable
off += 2;
ut8 segnum = *(bin->entry_table + off);
if ((off + 1) >= bin->ne_header->EntryTableLength) {
free(entry);
goto end;
}
ut8 segnum = rz_read_le8(bin->entry_table + off);
off++;
ut16 segoff = *(ut16 *)(bin->entry_table + off);
if (!segnum) {
if ((off + 2) >= bin->ne_header->EntryTableLength) {
wargio marked this conversation as resolved.
Show resolved Hide resolved
free(entry);
goto end;
}
ut16 segoff = rz_read_le16(bin->entry_table + off);
if (!segnum || segnum > bin->ne_header->SegCount) {
free(entry);
continue;
}
entry->paddr = (ut64)bin->segment_entries[segnum - 1].offset * bin->alignment + segoff;
} else { // Fixed
ut16 *p = (ut16 *)(bin->entry_table + off);
if (off >= bin->ne_header->EntryTableLength || bundle_type > bin->ne_header->SegCount) {
ut8 *p = bin->entry_table + off;
if ((off + 2) >= bin->ne_header->EntryTableLength || bundle_type > bin->ne_header->SegCount) {
free(entry);
continue;
goto end;
}
entry->paddr = (ut64)bin->segment_entries[bundle_type - 1].offset * bin->alignment + (*p);
entry->paddr = (ut64)bin->segment_entries[bundle_type - 1].offset * bin->alignment + rz_read_le16(p);
}
off += 2;
rz_list_append(entries, entry);
}
}
end:
rz_list_free(segments);
bin->entries = entries;
return entries;
Expand Down
Loading