Skip to content

Commit 848264c

Browse files
authored
Fix heap-buffer-overflow in macho parse_import_stub ##crash
- Reset nindirectsyms to 0 on all parse_dysymtab failure paths to prevent stale count when init_items fails but init() continues processing - Add NULL/bounds guards for indirectsyms and symtab at function entry - Fix off-by-one: idx >= nsymtab (not >) since symtab indices are 0-based - Use ut64 casts in bounds check to avoid signed/unsigned comparison issues - Remove redundant NULL checks now covered by early return
1 parent e1eddc7 commit 848264c

1 file changed

Lines changed: 16 additions & 9 deletions

File tree

libr/bin/format/mach0/mach0.c

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -758,24 +758,29 @@ static bool parse_dysymtab(struct MACH0_(obj_t) * mo, ut64 off) {
758758
mo->nindirectsyms = mo->dysymtab.nindirectsyms;
759759
if (mo->nindirectsyms > 0) {
760760
if (!UT32_MUL (&size_tab, mo->nindirectsyms, sizeof (ut32))) {
761+
mo->nindirectsyms = 0;
761762
return false;
762763
}
763764
if (!size_tab) {
765+
mo->nindirectsyms = 0;
764766
return false;
765767
}
766768
if (mo->dysymtab.indirectsymoff > mo->size ||
767769
mo->dysymtab.indirectsymoff + size_tab > mo->size) {
770+
mo->nindirectsyms = 0;
768771
return false;
769772
}
770773
if (! (mo->indirectsyms = calloc (mo->nindirectsyms, sizeof (ut32)))) {
771774
r_sys_perror ("calloc (indirectsyms)");
775+
mo->nindirectsyms = 0;
772776
return false;
773777
}
774778
for (i = 0; i < mo->nindirectsyms; i++) {
775779
len = r_buf_read_at (mo->b, mo->dysymtab.indirectsymoff + i * sizeof (ut32), idsyms, 4);
776780
if (len == -1) {
777781
R_LOG_ERROR ("read (indirect syms)");
778782
R_FREE (mo->indirectsyms);
783+
mo->nindirectsyms = 0;
779784
return false;
780785
}
781786
mo->indirectsyms[i] = r_read_ble32 (&idsyms[0], be);
@@ -2722,6 +2727,12 @@ static bool parse_import_stub(struct MACH0_(obj_t) * bin, struct symbol_t *symbo
27222727
if (!bin || !bin->sects) {
27232728
return false;
27242729
}
2730+
if (!bin->indirectsyms || bin->nindirectsyms <= 0) {
2731+
return false;
2732+
}
2733+
if (!bin->symtab || bin->nsymtab <= 0) {
2734+
return false;
2735+
}
27252736
for (i = 0; i < bin->nsects; i++) {
27262737
if ((bin->sects[i].flags & SECTION_TYPE) == S_SYMBOL_STUBS && bin->sects[i].reserved2 > 0) {
27272738
ut64 sect_size = bin->sects[i].size;
@@ -2736,17 +2747,13 @@ static bool parse_import_stub(struct MACH0_(obj_t) * bin, struct symbol_t *symbo
27362747
}
27372748
nsyms = (int) (sect_size / sect_fragment);
27382749
for (j = 0; j < nsyms; j++) {
2739-
if (bin->sects) {
2740-
if (bin->nindirectsyms < 0 || bin->sects[i].reserved1 + j >= bin->nindirectsyms) {
2741-
continue;
2742-
}
2750+
if ((ut64)bin->sects[i].reserved1 + j >= (ut64)bin->nindirectsyms) {
2751+
continue;
27432752
}
2744-
if (bin->indirectsyms) {
2745-
if (idx != bin->indirectsyms[bin->sects[i].reserved1 + j]) {
2746-
continue;
2747-
}
2753+
if (idx != bin->indirectsyms[bin->sects[i].reserved1 + j]) {
2754+
continue;
27482755
}
2749-
if (idx > bin->nsymtab) {
2756+
if (idx >= bin->nsymtab) {
27502757
continue;
27512758
}
27522759
symbol->type = R_BIN_MACH0_SYMBOL_TYPE_LOCAL;

0 commit comments

Comments
 (0)