CVE-2017-15368 (published 2017-10-16T01:29Z)

The wasm_dis function in libr/asm/arch/wasm/wasm.c in radare2 2.0.0 allows remote attackers to cause a denial of service (stack-based buffer over-read and application crash) or possibly have unspecified other impact via a crafted WASM file that triggers an incorrect r_hex_bin2str call.

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

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

Fix information:
repo_url: https://github.com/radare/radare2
commit_details: repo_url: https://github.com/radare/radare2
author: pancake
author_date: 2017-10-11 19:02:25+02:00
msg: Fix crash in wasm disassembler
repository: repo_url: https://github.com/radare/radare2
repo_name: radareorg/radare2
description: UNIX-like reverse engineering framework and command-line toolset
repo_language: C
owner: radare
file_changes: filename: wasm.c
change_type: ModificationType.MODIFY
diff: @@ -416,7 +416,9 @@ int wasm_asm(const char *str, unsigned char *buf, int buf_len) {
 int wasm_dis(WasmOp *op, const unsigned char *buf, int buf_len) {
 	op->len = 1;
 	op->op = buf[0];
-	if (op->op > 0xbf) return 1;
+	if (op->op > 0xbf) {
+		return 1;
+	}
 	// add support for extension opcodes (SIMD + atomics)
 	WasmOpDef *opdef = &opcodes[op->op];
 	switch (op->op) {
@@ -599,28 +601,37 @@ int wasm_dis(WasmOp *op, const unsigned char *buf, int buf_len) {
 		{
 			ut32 count = 0, *table = NULL, def = 0;
 			size_t n = read_u32_leb128 (buf + 1, buf + buf_len, &count);
-			if (!(n > 0 && n < buf_len)) goto err;
-			if (!(table = calloc (count, sizeof (ut32)))) goto err;
+			if (!(n > 0 && n < buf_len)) {
+				goto err;
+			}
+			if (!(table = calloc (count, sizeof (ut32)))) {
+				goto err;
+			}
 			int i = 0;
 			op->len += n;
 			for (i = 0; i < count; i++) {
 				n = read_u32_leb128 (buf + op->len, buf + buf_len, &table[i]);
-				if (!(op->len + n <= buf_len)) goto beach;
+				if (!(op->len + n <= buf_len)) {
+					goto beach;
+				}
 				op->len += n;
 			}
 			n = read_u32_leb128 (buf + op->len, buf + buf_len, &def);
-			if (!(n > 0 && n + op->len < buf_len)) goto beach;
+			if (!(n > 0 && n + op->len < buf_len)) {
+				goto beach;
+			}
 			op->len += n;
 			snprintf (op->txt, R_ASM_BUFSIZE, "%s %d ", opdef->txt, count);
-			for (i = 0; i < count && strlen (op->txt) < R_ASM_BUFSIZE; i++) {
-				snprintf (op->txt + strlen (op->txt), R_ASM_BUFSIZE, "%d ", table[i]);
+			for (i = 0; i < count && strlen (op->txt) + 10 < R_ASM_BUFSIZE; i++) {
+				int optxtlen = strlen (op->txt);
+				snprintf (op->txt + optxtlen, R_ASM_BUFSIZE - optxtlen, "%d ", table[i]);
 			}	
 			snprintf (op->txt + strlen (op->txt), R_ASM_BUFSIZE, "%d", def);
 			free (table);
 			break;
 			beach:
-				free (table);
-				goto err;
+			free (table);
+			goto err;
 		}
 		break;
 	case WASM_OP_CALLINDIRECT:
@@ -744,4 +755,3 @@ err:
 	snprintf (op->txt, R_ASM_BUFSIZE, "invalid");
 	return op->len;
 }
-

programming_language: Lua
filename: flag.c
change_type: ModificationType.MODIFY
diff: @@ -74,7 +74,7 @@ static ut64 num_callback(RNum *user, const char *name, int *ok) {
 	dir == -1 -> result <= off
 	dir == 0 ->  result == off
 	dir == 1 ->  result >= off*/
-static  RFlagsAtOffset* r_flag_get_nearest_list(RFlag *f, ut64 off, int dir) {
+static RFlagsAtOffset* r_flag_get_nearest_list(RFlag *f, ut64 off, int dir) {
 	RFlagsAtOffset *flags = NULL;
 	RFlagsAtOffset key;
 	key.off = off;

programming_language: C