Skip to content

Commit

Permalink
Fix oobread segfaults in the NE bin parser ##crash
Browse files Browse the repository at this point in the history
* Reported by @Han0nly via huntr.dev
* Reproducers: seed1 seed2
* BountyID: ad3c9c4c-76e7-40c8-bd4a-c095acd8bb40
  • Loading branch information
radare authored and trufae committed Apr 5, 2022
1 parent 7c495b7 commit 2d782cd
Showing 1 changed file with 24 additions and 7 deletions.
31 changes: 24 additions & 7 deletions libr/bin/format/ne/ne.c
@@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2019 - GustavoLCR */
/* radare - LGPL - Copyright 2019-2022 - GustavoLCR */

#include "ne.h"

Expand Down Expand Up @@ -83,10 +83,10 @@ RList *r_bin_ne_get_segments(r_bin_ne_obj_t *bin) {
RList *segments = r_list_newf (free);
for (i = 0; i < bin->ne_header->SegCount; i++) {
RBinSection *bs = R_NEW0 (RBinSection);
NE_image_segment_entry *se = &bin->segment_entries[i];
if (!bs) {
return segments;
}
NE_image_segment_entry *se = &bin->segment_entries[i];
bs->size = se->length;
bs->vsize = se->minAllocSz ? se->minAllocSz : 64000;
bs->bits = R_SYS_BITS_16;
Expand Down Expand Up @@ -425,7 +425,7 @@ RList *r_bin_ne_get_relocs(r_bin_ne_obj_t *bin) {
return NULL;
}

ut16 *modref = malloc (bin->ne_header->ModRefs * sizeof (ut16));
ut16 *modref = calloc (bin->ne_header->ModRefs, sizeof (ut16));
if (!modref) {
return NULL;
}
Expand All @@ -451,7 +451,8 @@ RList *r_bin_ne_get_relocs(r_bin_ne_obj_t *bin) {
continue;
}
off += 2;
while (off < start + length * sizeof (NE_image_reloc_item)) {
size_t buf_size = r_buf_size (bin->buf);
while (off < start + length * sizeof (NE_image_reloc_item) && off < buf_size) {
RBinReloc *reloc = R_NEW0 (RBinReloc);
if (!reloc) {
return NULL;
Expand Down Expand Up @@ -484,10 +485,11 @@ RList *r_bin_ne_get_relocs(r_bin_ne_obj_t *bin) {
break;
}
char *name;
if (rel.index > bin->ne_header->ModRefs) {
if (rel.index < 1 || rel.index > bin->ne_header->ModRefs) {
name = r_str_newf ("UnknownModule%d_%x", rel.index, off); // ????
} else {
offset = modref[rel.index - 1] + bin->header_offset + bin->ne_header->ImportNameTable;
int index = rel.index;
offset = modref[index - 1] + bin->header_offset + bin->ne_header->ImportNameTable;
name = __read_nonnull_str_at (bin->buf, offset);
}
if (rel.flags & IMPORTED_ORD) {
Expand Down Expand Up @@ -563,16 +565,31 @@ void __init(RBuffer *buf, r_bin_ne_obj_t *bin) {
return;
}
bin->buf = buf;
// XXX this is endian unsafe
r_buf_read_at (buf, bin->header_offset, (ut8 *)bin->ne_header, sizeof (NE_image_header));
if (bin->ne_header->FileAlnSzShftCnt > 8) {
bin->ne_header->FileAlnSzShftCnt = 8;
}
if (bin->ne_header->ModRefs * sizeof (ut16) >= r_buf_size (bin->buf)) {
bin->ne_header->ModRefs = r_buf_size (bin->buf) / sizeof (ut16);
}
bin->alignment = 1 << bin->ne_header->FileAlnSzShftCnt;
if (!bin->alignment) {
bin->alignment = 1 << 9;
}
bin->os = __get_target_os (bin);

ut16 offset = bin->ne_header->SegTableOffset + bin->header_offset;
ut16 size = bin->ne_header->SegCount * sizeof (NE_image_segment_entry);
size_t size = bin->ne_header->SegCount * sizeof (NE_image_segment_entry);
if (offset >= r_buf_size (bin->buf)) {
return;
}
size_t remaining = r_buf_size (bin->buf) - offset;
size = R_MIN (remaining, size);
bin->segment_entries = calloc (1, size);
if (size >= remaining) {
bin->ne_header->SegCount = size / sizeof (NE_image_segment_entry);
}
if (!bin->segment_entries) {
return;
}
Expand Down

0 comments on commit 2d782cd

Please sign in to comment.