Commit message: Fix oobread bug in NE parser ##crash

* Reported by @cnitlrt via huntrdev
* BountyID: 02b4b563-b946-4343-9092-38d1c5cd60c9
* Reproducer: neoobread
CVE: CVE-2022-1383
CWE: CWE-787
Vulnerability description: Heap-based Buffer Overflow in GitHub repository radareorg/radare2 prior to 5.6.8. The bug causes the program reads data past the end of the intented buffer. Typically, this can allow attackers to read sensitive information from other memory locations or cause a crash.

Project: radare2
File: coresymbolication.c

static void r_coresym_cache_element_section_fini(RCoreSymCacheElementSection *sec) {
	if (sec) {
		free (sec->name);
	}
}

Project: radare2
File: coresymbolication.c

static RCoreSymCacheElementHdr *r_coresym_cache_element_header_new(RBuffer *buf, size_t off, int bits) {
	RCoreSymCacheElementHdr *hdr = R_NEW0 (RCoreSymCacheElementHdr);
	if (hdr && r_buf_fread_at (buf, off, (ut8 *)hdr, "13i16c5i", 1) == sizeof (RCoreSymCacheElementHdr)) {
		return hdr;
	}
	free (hdr);
	return NULL;
}

Project: radare2
File: coresymbolication.c

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

Project: radare2
File: coresymbolication.c

ut64 r_coresym_cache_element_pa2va(RCoreSymCacheElement *element, ut64 pa) {
	size_t i;
	for (i = 0; i < element->hdr->n_segments; i++) {
		RCoreSymCacheElementSegment *seg = &element->segments[i];
		if (seg->size == 0) {
			continue;
		}
		if (seg->paddr < pa && pa < seg->paddr + seg->size) {
			return pa - seg->paddr + seg->vaddr;
		}
	}
	return pa;
}

Project: radare2
File: coresymbolication.c

static void r_coresym_cache_element_symbol_fini(RCoreSymCacheElementSymbol *sym) {
	if (sym) {
		free (sym->name);
		free (sym->mangled_name);
	}
}

Project: radare2
File: coresymbolication.c

static void r_coresym_cache_element_segment_fini(RCoreSymCacheElementSegment *seg) {
	if (seg) {
		free (seg->name);
	}
}

Project: radare2
File: coresymbolication.c

static char *str_dup_safe_fixed(const ut8 *b, const ut8 *str, ut64 len, const ut8 *end) {
	if (str >= b && str + len < end) {
		char *result = calloc (1, len + 1);
		if (result) {
			r_str_ncpy (result, (const char *)str, len);
			return result;
		}
	}
	return NULL;
}

Project: radare2
File: coresymbolication.c

static void meta_add_fileline(RBinFile *bf, ut64 vaddr, ut32 size, RCoreSymCacheElementFLC *flc) {
	Sdb *s = bf->sdb_addrinfo;
	if (!s) {
		return;
	}
	char aoffset[64];
	ut64 cursor = vaddr;
	ut64 end = cursor + R_MAX (size, 1);
	char *fileline = r_str_newf ("%s:%d", flc->file, flc->line);
	while (cursor < end) {
		char *aoffsetptr = sdb_itoa (cursor, aoffset, 16);
		if (!aoffsetptr) {
			break;
		}
		sdb_set (s, aoffsetptr, fileline, 0);
		sdb_set (s, fileline, aoffsetptr, 0);
		cursor += 2;
	}
	free (fileline);
}

Project: radare2
File: coresymbolication.c

void r_coresym_cache_element_free(RCoreSymCacheElement *element) {
	if (!element) {
		return;
	}
	size_t i;
	if (element->segments) {
		for (i = 0; i < element->hdr->n_segments; i++) {
			r_coresym_cache_element_segment_fini (&element->segments[i]);
		}
	}
	if (element->sections) {
		for (i = 0; i < element->hdr->n_sections; i++) {
			r_coresym_cache_element_section_fini (&element->sections[i]);
		}
	}
	if (element->symbols) {
		for (i = 0; i < element->hdr->n_symbols; i++) {
			r_coresym_cache_element_symbol_fini (&element->symbols[i]);
		}
	}
	if (element->lined_symbols) {
		for (i = 0; i < element->hdr->n_lined_symbols; i++) {
			r_coresym_cache_element_lined_symbol_fini (&element->lined_symbols[i]);
		}
	}
	if (element->line_info) {
		for (i = 0; i < element->hdr->n_line_info; i++) {
			r_coresym_cache_element_line_info_fini (&element->line_info[i]);
		}
	}
	free (element->segments);
	free (element->sections);
	free (element->symbols);
	free (element->lined_symbols);
	free (element->line_info);
	free (element->hdr);
	free (element->file_name);
	free (element->binary_version);
	free (element);
}

Project: radare2
File: coresymbolication.c

static void r_coresym_cache_element_lined_symbol_fini(RCoreSymCacheElementLinedSymbol *sym) {
	if (sym) {
		r_coresym_cache_element_symbol_fini (&sym->sym);
		r_coresym_cache_element_flc_fini (&sym->flc);
	}
}

Project: radare2
File: coresymbolication.c

static void r_coresym_cache_element_line_info_fini(RCoreSymCacheElementLineInfo *line) {
	if (line) {
		r_coresym_cache_element_flc_fini (&line->flc);
	}
}

Project: radare2
File: coresymbolication.c

static void r_coresym_cache_element_flc_fini(RCoreSymCacheElementFLC *flc) {
	if (flc) {
		free (flc->file);
	}
}