Skip to content

Commit

Permalink
Fix heap OOB read in macho.iterate_chained_fixups ##crash
Browse files Browse the repository at this point in the history
* Reported by peacock-doris via huntr.dev
* Reproducer 'tests_65305'

mrmacete:
* Return early if segs_count is 0
* Initialize segs_count also for reconstructed fixups

Co-authored-by: pancake <pancake@nopcode.org>
Co-authored-by: Francesco Tamagni <mrmacete@protonmail.ch>
  • Loading branch information
3 people committed Mar 22, 2022
1 parent 0be8f25 commit 0052500
Show file tree
Hide file tree
Showing 3 changed files with 8 additions and 5 deletions.
10 changes: 6 additions & 4 deletions libr/bin/format/mach0/mach0.c
Expand Up @@ -1510,10 +1510,11 @@ static bool parse_chained_fixups(struct MACH0_(obj_t) *bin, ut32 offset, ut32 si
if (header.starts_offset > size) {
return false;
}
ut32 segs_count;
if ((segs_count = r_buf_read_le32_at (bin->b, starts_at)) == UT32_MAX) {
ut32 segs_count = r_buf_read_le32_at (bin->b, starts_at);
if (segs_count == UT32_MAX || segs_count == 0) {
return false;
}
bin->segs_count = segs_count;
bin->chained_starts = R_NEWS0 (struct r_dyld_chained_starts_in_segment *, segs_count);
if (!bin->chained_starts) {
return false;
Expand Down Expand Up @@ -1699,6 +1700,7 @@ static bool reconstruct_chained_fixup(struct MACH0_(obj_t) *bin) {
}
R_FREE (opcodes);

bin->segs_count = bin->nsegs;
return true;
}

Expand Down Expand Up @@ -2124,7 +2126,7 @@ void *MACH0_(mach0_free)(struct MACH0_(obj_t) *mo) {
free (mo->intrp);
free (mo->compiler);
if (mo->chained_starts) {
for (i = 0; i < mo->nsegs; i++) {
for (i = 0; i < mo->nsegs && i < mo->segs_count; i++) {
if (mo->chained_starts[i]) {
free (mo->chained_starts[i]->page_start);
free (mo->chained_starts[i]);
Expand Down Expand Up @@ -4558,7 +4560,7 @@ struct MACH0_(mach_header) *MACH0_(get_hdr)(RBuffer *buf) {

void MACH0_(iterate_chained_fixups)(struct MACH0_(obj_t) *bin, ut64 limit_start, ut64 limit_end, ut32 event_mask, RFixupCallback callback, void * context) {
int i = 0;
for (; i < bin->nsegs; i++) {
for (; i < bin->nsegs && i < bin->segs_count; i++) {
if (!bin->chained_starts[i]) {
continue;
}
Expand Down
1 change: 1 addition & 0 deletions libr/bin/format/mach0/mach0.h
Expand Up @@ -130,6 +130,7 @@ struct MACH0_(obj_t) {
char *intrp;
char *compiler;
int nsegs;
int segs_count;
struct r_dyld_chained_starts_in_segment **chained_starts;
struct dyld_chained_fixups_header fixups_header;
ut64 fixups_offset;
Expand Down
2 changes: 1 addition & 1 deletion libr/core/cmd_api.c
Expand Up @@ -391,7 +391,7 @@ R_API int r_cmd_alias_set_raw(RCmd *cmd, const char *k, const ut8 *v, int sz) {

R_API RCmdAliasVal *r_cmd_alias_get(RCmd *cmd, const char *k) {
r_return_val_if_fail (cmd && cmd->aliases && k, NULL);
return ht_pp_find(cmd->aliases, k, NULL);
return ht_pp_find (cmd->aliases, k, NULL);
}

static ut8 *alias_append_internal(int *out_szp, const RCmdAliasVal *first, const ut8 *second, int second_sz) {
Expand Down

0 comments on commit 0052500

Please sign in to comment.