CVE-2022-1437 (published 2022-04-22T15:15Z)

Heap-based Buffer Overflow in GitHub repository radareorg/radare2 prior to 5.7.0. 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.

Severity: MEDIUM
CVSS v2 base score: 5.8 (AV:N/AC:M/Au:N/C:P/I:N/A:P)
CVSS v3 base score: 7.1, HIGH (CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:N/A:H)

Weakness information:
cwe_id: CWE-787
cwe_name: Out-of-bounds Write
description: The product writes data past the end, or before the beginning, of the intended buffer.
extended_description: 
            
            
             
			 
         
         

Fix information:
repo_url: https://github.com/radareorg/radare2
commit_details: repo_url: https://github.com/radareorg/radare2
author: pancake
author_date: 2022-04-21 18:22:00+02:00
msg: Fix oobread and null deref in symbols file parser ##crash

* Reported by @cnitlrt
* BountyID: af6c3e9e-b7df-4d80-b48f-77fdd17b4038/
* Reproducer: symoob
repository: repo_url: https://github.com/radareorg/radare2
repo_name: radareorg/radare2
description: UNIX-like reverse engineering framework and command-line toolset
repo_language: C
owner: radareorg
file_changes: filename: coresymbolication.c
change_type: ModificationType.MODIFY
diff: @@ -269,6 +269,9 @@ RCoreSymCacheElement *r_coresym_cache_element_new(RBinFile *bf, RBuffer *buf, ut
 		for (i = 0; i < hdr->n_sections && cursor < end; i++) {
 			ut8 *sect_start = cursor;
 			RCoreSymCacheElementSection *sect = &result->sections[i];
+			if (cursor + (word_size * 4) > end) {
+				goto beach;
+			}
 			sect->vaddr = sect->paddr = r_read_ble (cursor, false, bits);
 			if (sect->vaddr < page_zero_size) {
 				sect->vaddr += page_zero_size;
@@ -359,6 +362,10 @@ RCoreSymCacheElement *r_coresym_cache_element_new(RBinFile *bf, RBuffer *buf, ut
 				continue;
 			}
 			string_origin = relative_to_strings? b + start_of_strings : cursor;
+			if (!string_origin) {
+				cursor += R_CS_EL_SIZE_LSYM;
+				continue;
+			}
 			lsym->flc.file = str_dup_safe (b, string_origin + file_name_off, end);
 			if (!lsym->flc.file) {
 				cursor += R_CS_EL_SIZE_LSYM;

programming_language: C
filename: bin_symbols.c
change_type: ModificationType.MODIFY
diff: @@ -353,28 +353,30 @@ static bool check_buffer(RBinFile *bf, RBuffer *b) {
 }
 
 static RList *symbols(RBinFile *bf) {
-	RList *res = r_list_newf ((RListFree)r_bin_symbol_free);
-	r_return_val_if_fail (res && bf->o && bf->o->bin_obj, res);
+	r_return_val_if_fail (bf && bf->o && bf->o->bin_obj, NULL);
 	RCoreSymCacheElement *element = bf->o->bin_obj;
 	size_t i;
 	HtUU *hash = ht_uu_new0 ();
 	if (!hash) {
-		return res;
+		return NULL;
 	}
+	RList *res = r_list_newf ((RListFree)r_bin_symbol_free);
 	bool found = false;
-	for (i = 0; i < element->hdr->n_lined_symbols; i++) {
-		RCoreSymCacheElementSymbol *sym = (RCoreSymCacheElementSymbol *)&element->lined_symbols[i];
-		if (!sym) {
-			break;
-		}
-		ht_uu_find (hash, sym->paddr, &found);
-		if (found) {
-			continue;
-		}
-		RBinSymbol *s = bin_symbol_from_symbol (element, sym);
-		if (s) {
-			r_list_append (res, s);
-			ht_uu_insert (hash, sym->paddr, 1);
+	if (element->lined_symbols) {
+		for (i = 0; i < element->hdr->n_lined_symbols; i++) {
+			RCoreSymCacheElementSymbol *sym = (RCoreSymCacheElementSymbol *)&element->lined_symbols[i];
+			if (!sym) {
+				break;
+			}
+			ht_uu_find (hash, sym->paddr, &found);
+			if (found) {
+				continue;
+			}
+			RBinSymbol *s = bin_symbol_from_symbol (element, sym);
+			if (s) {
+				r_list_append (res, s);
+				ht_uu_insert (hash, sym->paddr, 1);
+			}
 		}
 	}
 	if (element->symbols) {

programming_language: C