CVE-2023-4322 (published 2023-08-14T16:15Z)

Heap-based Buffer Overflow in GitHub repository radareorg/radare2 prior to 5.9.0.

CVSS v3 base score: 9.8, CRITICAL (CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/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: 2023-08-14 15:56:13+02:00
msg: Fix 1byte heap oobread in the brainfuck disassembler

* https://huntr.dev/bounties/06e2484c-d6f1-4497-af67-26549be9fffd/
* Kudos to @7resp4ss for reporting
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: plugin.c
change_type: ModificationType.MODIFY
diff: @@ -13,8 +13,8 @@ static size_t countChar(const ut8 *buf, int len, char ch) {
 }
 
 static int getid(char ch) {
-	const char *keys = "[]<>+-,.";
-	const char *cidx = strchr (keys, ch);
+	const char *const keys = "[]<>+-,.";
+	const char *const cidx = strchr (keys, ch);
 	return cidx? cidx - keys + 1: 0;
 }
 
@@ -136,13 +136,11 @@ static int assemble(const char *buf, ut8 **outbuf) {
 #define BUFSIZE_INC 32
 static bool decode(RArchSession *as, RAnalOp *op, RArchDecodeMask mask) {
 	int len = op->size;
-	const ut8 *_buf = op->bytes;
-	const ut64 addr = op->addr;
 	if (len < 1) {
 		return false;
 	}
-
-	ut8 *buf = (ut8*)_buf; // XXX
+	ut8 *buf = op->bytes;
+	const ut64 addr = op->addr;
 	ut64 dst = 0LL;
 	if (!op) {
 		return 1;
@@ -169,29 +167,32 @@ static bool decode(RArchSession *as, RAnalOp *op, RArchDecodeMask mask) {
 		}
 		r_strbuf_set (&op->esil, "1,pc,-,brk,=[4],4,brk,+=");
 #if 1
-		{
+		if (len > 1) {
 			const ut8 *p = buf + 1;
 			int lev = 0, i = 1;
 			len--;
 			while (i < len && *p) {
-				if (*p == '[') {
+				switch (*p) {
+				case '[':
 					lev++;
-				}
-				if (*p == ']') {
+					break;
+				case ']':
 					lev--;
-					if (lev == -1) {
-						dst = addr + (size_t)(p - buf) + 1;
+					if (lev < 1) {
+						size_t delta = p - buf;
+						dst = addr + (size_t)delta + 1;
 						op->jump = dst;
 						r_strbuf_set (&op->esil, "1,pc,-,brk,=[4],4,brk,+=,");
 						goto beach;
 					}
-				}
-				if (*p == 0x00 || *p == 0xff) {
+					break;
+				case 0:
+				case 0xff:
 					op->type = R_ANAL_OP_TYPE_ILL;
 					goto beach;
 				}
 				if (read_at && i == len - 1) {
-					break;
+#if 0
 					// XXX unnecessary just break
 					int new_buf_len = len + 1 + BUFSIZE_INC;
 					ut8 *new_buf = calloc (new_buf_len, 1);
@@ -203,6 +204,9 @@ static bool decode(RArchSession *as, RAnalOp *op, RArchDecodeMask mask) {
 						p = buf + i;
 						len += BUFSIZE_INC;
 					}
+#else
+					break;
+#endif
 				}
 				p++;
 				i++;

programming_language: C
filename: cmd_anal.c
change_type: ModificationType.MODIFY
diff: @@ -8719,9 +8719,9 @@ static void _anal_calls(RCore *core, ut64 addr, ut64 addr_end, bool printCommand
 					isValidCall = false;
 				}
 				if (isValidCall) {
-					ut8 buf[4] = {0};
-					r_io_read_at (core->io, op.jump, buf, 4);
-					isValidCall = memcmp (buf, "\x00\x00\x00\x00", 4);
+					ut8 zbuf[4] = {0};
+					r_io_read_at (core->io, op.jump, zbuf, 4);
+					isValidCall = memcmp (zbuf, "\x00\x00\x00\x00", 4);
 				}
 				if (isValidCall) {
 #if JAYRO_03
@@ -8817,9 +8817,8 @@ static void cmd_anal_calls(RCore *core, const char *input, bool printCommands, b
 }
 
 static void cmd_sdbk(Sdb *db, const char *input) {
-	char *out = (input[0] == ' ')
-		? sdb_querys (db, NULL, 0, input + 1)
-		: sdb_querys (db, NULL, 0, "*");
+	const char *arg = (input[0] == ' ')? input + 1: "*";
+	char *out = sdb_querys (db, NULL, 0, arg);
 	if (out) {
 		r_cons_println (out);
 		free (out);
@@ -9118,7 +9117,7 @@ static void anal_axg(RCore *core, const char *input, int level, Sdb *db, int opt
 }
 
 static void cmd_anal_ucall_ref(RCore *core, ut64 addr) {
-	RAnalFunction * fcn = r_anal_get_function_at (core->anal, addr);
+	RAnalFunction *fcn = r_anal_get_function_at (core->anal, addr);
 	if (fcn) {
 		r_cons_printf (" ; %s", fcn->name);
 	} else {
@@ -9257,7 +9256,6 @@ static void axfm(RCore *core) {
 			last_addr = ref->addr;
 		}
 	}
-
 	RVecAnalRef_free (refs);
 }
 

programming_language: Go