CVE-2022-0676: Out-of-bounds Write (CWE-787)
value: Heap-based Buffer Overflow in GitHub repository radareorg/radare2 prior to 5.6.4.
CWE description: The product writes data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 7.8
Published: 2022-02-22T00:15Z
Repository: https://github.com/radareorg/radare2
Language: C
Files changed: libr/bin/p/bin_dyldcache.c
Commit date: 2022-02-18 12:45:44 +0100
Commit message: Fix heap buffer overflow in dyldcache parser ##crash

* Reported by: Lazymio via huntr.dev
* Reproducer: dyldovf

Diff: diff --git a/libr/bin/p/bin_dyldcache.c b/libr/bin/p/bin_dyldcache.c
index d76699b72f7..6b7b512b713 100644
--- a/libr/bin/p/bin_dyldcache.c
+++ b/libr/bin/p/bin_dyldcache.c
@@ -1142,10 +1142,12 @@ static ut64 resolve_symbols_off(RDyldCache *cache, ut64 pa) {
 	return 0;
 }
 
 static RList *create_cache_bins(RBinFile *bf, RDyldCache *cache) {
 	RList *bins = r_list_newf ((RListFree)free_bin);
+	ut16 *depArray = NULL;
+	cache_imgxtr_t *extras = NULL;
 	if (!bins) {
 		return NULL;
 	}
 
 	char *target_libs = NULL;
@@ -1175,12 +1177,10 @@ static RList *create_cache_bins(RBinFile *bf, RDyldCache *cache) {
 		if (!img) {
 			goto next;
 		}
 
 		ut32 j;
-		ut16 *depArray = NULL;
-		cache_imgxtr_t *extras = NULL;
 		if (target_libs) {
 			HtPU *path_to_idx = NULL;
 			if (cache->accel) {
 				depArray = R_NEWS0 (ut16, cache->accel->depListCount);
 				if (!depArray) {
@@ -1732,16 +1732,16 @@ static void populate_cache_maps(RDyldCache *cache) {
 
 	cache->maps = maps;
 	cache->n_maps = next_map;
 }
 
-static cache_accel_t *read_cache_accel(RBuffer *cache_buf, cache_hdr_t *hdr, cache_map_t *maps) {
+static cache_accel_t *read_cache_accel(RBuffer *cache_buf, cache_hdr_t *hdr, cache_map_t *maps, int n_maps) {
 	if (!cache_buf || !hdr || !hdr->accelerateInfoSize || !hdr->accelerateInfoAddr) {
 		return NULL;
 	}
-
-	ut64 offset = va2pa (hdr->accelerateInfoAddr, hdr->mappingCount, maps, cache_buf, 0, NULL, NULL);
+	size_t mc = R_MIN (hdr->mappingCount, n_maps);
+	ut64 offset = va2pa (hdr->accelerateInfoAddr, mc, maps, cache_buf, 0, NULL, NULL);
 	if (!offset) {
 		return NULL;
 	}
 
 	ut64 size = sizeof (cache_accel_t);
@@ -1893,11 +1893,11 @@ static bool load_buffer(RBinFile *bf, void **bin_obj, RBuffer *buf, ut64 loadadd
 	populate_cache_maps (cache);
 	if (!cache->maps) {
 		r_dyldcache_free (cache);
 		return false;
 	}
-	cache->accel = read_cache_accel (cache->buf, cache->hdr, cache->maps);
+	cache->accel = read_cache_accel (cache->buf, cache->hdr, cache->maps, cache->n_maps);
 	cache->bins = create_cache_bins (bf, cache);
 	if (!cache->bins) {
 		r_dyldcache_free (cache);
 		return false;
 	}

Vulnerable code: 		ut16 *depArray = NULL;
		cache_imgxtr_t *extras = NULL;
static cache_accel_t *read_cache_accel(RBuffer *cache_buf, cache_hdr_t *hdr, cache_map_t *maps) {

	ut64 offset = va2pa (hdr->accelerateInfoAddr, hdr->mappingCount, maps, cache_buf, 0, NULL, NULL);
	cache->accel = read_cache_accel (cache->buf, cache->hdr, cache->maps);
Fixed code: 	ut16 *depArray = NULL;
	cache_imgxtr_t *extras = NULL;
static cache_accel_t *read_cache_accel(RBuffer *cache_buf, cache_hdr_t *hdr, cache_map_t *maps, int n_maps) {
	size_t mc = R_MIN (hdr->mappingCount, n_maps);
	ut64 offset = va2pa (hdr->accelerateInfoAddr, mc, maps, cache_buf, 0, NULL, NULL);
	cache->accel = read_cache_accel (cache->buf, cache->hdr, cache->maps, cache->n_maps);