CVE-2017-6448 (C, published 2017-04-03T05:59Z)
Description: value: The dalvik_disassemble function in libr/asm/p/asm_dalvik.c in radare2 1.2.1 allows remote attackers to cause a denial of service (stack-based buffer overflow and application crash) or possibly have unspecified other impact via a crafted DEX file.
Severity: MEDIUM (CVSS v3 base score: 7.8)
Weakness: CWE-119 \u2014 Improper Restriction of Operations within the Bounds of a Memory Buffer
The product performs operations on a memory buffer, but it reads from or writes to a memory location outside the buffer's intended boundary. This may result in read or write operations on unexpected memory locations that could be linked to other variables, data structures, or internal program data.
Repository: https://github.com/radare/radare2
Files changed:
libr/asm/p/asm_dalvik.c
Commit message: Fix #6885 - oob write in dalvik_disassemble


Vulnerable code:
				sprintf (op->buf_asm, "packed-switch-payload %d, %d", array_size, first_key);
				sprintf (op->buf_asm, "sparse-switch-payload %d", array_size);
			sprintf (str, " v%i, v%i", vA, vB);
			sprintf (str, " v%i, v%i", vA, vB);
			sprintf (str, " v%i, v%i", vA, vB);
			sprintf (str, " v%i", vA);
			sprintf (str, " v%i, %#x", vA, vB);
				sprintf (str, " v%i, %#04hx", vA, sB);
			sprintf (str, " v%i:v%i, 0x%"PFMT64x, vA, vA + 1, lB);
			sprintf (str, " v%i, v%i, v%i", vA, vB, vC);
			sprintf (str, " v%i, v%i, %#x", vA, vB, vC);
			sprintf (str, " v%i, v%i, %#x", vA, vB, vC);
			//sprintf (str, " %i", vA*2); // vA : word -> byte
			//sprintf (str, " v%i, %i", vA, vB);
			//sprintf (str, " %#08x", vA*2); // vA: word -> byte
			//sprintf (str, " v%i, v%i, %i", vA, vB, vC);
				sprintf (str, " {v%i}", buf[4] & 0x0f);
				sprintf (str, " {v%i, v%i}", buf[4] & 0x0f, (buf[4] & 0xf0) >> 4);
				sprintf (str, " {v%i, v%i, v%i}", buf[4] & 0x0f, (buf[4] & 0xf0) >> 4, buf[5] & 0x0f);
				sprintf (str, " {v%i, v%i, v%i, v%i}", buf[4] & 0x0f,
				sprintf (str, " {}");
			sprintf (str, ", [%04x]", vB);
			sprintf (str, " {v%i..v%i}, [%04x]", vC, vC + vA - 1, vB);
				sprintf (str, " {v%i}", buf[4] & 0x0f);
				sprintf (str, " {v%i, v%i}", buf[4] & 0x0f, (buf[4] & 0xf0) >> 4);
				sprintf (str, " {v%i, v%i, v%i}", buf[4] & 0x0f,
				sprintf (str, " {v%i, v%i, v%i, v%i}", buf[4] & 0x0f,
				sprintf (str, " {}");
			sprintf (str, ", [%04x]", vB);
					sprintf (str, " v%i, string+%i", vA, vB);
					sprintf (str, " v%i, 0x%"PFMT64x, vA, offset);
					sprintf (str, " v%i, class+%i", vA, vB);
					sprintf (str, " v%i, %s", vA, flag_str);
					sprintf (str, " v%i, field+%i", vA, vB);
					sprintf (str, " v%i, %s", vA, flag_str);
				sprintf (str, " v%i, v%i, [obj+%04x]", vA, vB, vC);
				sprintf (str, " v%i, v%i, [0x%"PFMT64x"]", vA, vB, offset);
				sprintf (str, " v%i, thing+%i", vA, vB);
				sprintf (str, " v%i, 0x%"PFMT64x, vA, offset);
					sprintf (str, " v%i, v%i, %s", vA, vB, flag_str);
					sprintf (str, " v%i, v%i, class+%i", vA, vB, vC);
					sprintf (str, " v%i, v%i, %s", vA, vB, flag_str);
					sprintf (str, " v%i, v%i, field+%i", vA, vB, vC);
				sprintf (str, " v%i, string+%i", vA, vB);
				sprintf (str, " v%i, 0x%"PFMT64x, vA, offset);
					sprintf (str, " {v%i..v%i}, %s", vC, vC + vA - 1, flag_str);
					sprintf (str, " {v%i..v%i}, class+%i", vC, vC + vA - 1, vB);
					sprintf (str, " {v%i..v%i}, %s", vC, vC + vA - 1, flag_str);
					sprintf (str, " {v%i..v%i}, method+%i", vC, vC + vA - 1, vB);
					sprintf (str, " {v%i}", buf[4] & 0x0f);
					sprintf (str, " {v%i, v%i}", buf[4] & 0x0f, (buf[4] & 0xf0) >> 4);
					sprintf (str, " {v%i, v%i, v%i}", buf[4] & 0x0f,
					sprintf (str, " {v%i, v%i, v%i, v%i}", buf[4] & 0x0f,
					sprintf (str, " {v%i, v%i, v%i, v%i, v%i}", buf[4] & 0x0f,
					sprintf (str, " {}");
					sprintf (str, ", %s ; 0x%x", flag_str, vB);
					sprintf (str, ", class+%i", vB);
					sprintf (str, ", %s ; 0x%x", flag_str, vB);
					sprintf (str, ", method+%i", vB);

Fixed code:
				snprintf (op->buf_asm, sizeof(op->buf_asm), "packed-switch-payload %d, %d", array_size, first_key);
				snprintf (op->buf_asm, sizeof (op->buf_asm), "sparse-switch-payload %d", array_size);
			snprintf (str, sizeof (str), " v%i, v%i", vA, vB);
			snprintf (str, sizeof (str), " v%i, v%i", vA, vB);
			snprintf (str, sizeof (str), " v%i, v%i", vA, vB);
			snprintf (str, sizeof (str), " v%i", vA);
			snprintf (str, sizeof (str), " v%i, %#x", vA, vB);
				snprintf (str, sizeof (str), " v%i, %#04hx", vA, sB);
			snprintf (str, sizeof (str), " v%i:v%i, 0x%"PFMT64x, vA, vA + 1, lB);
			snprintf (str, sizeof (str), " v%i, v%i, v%i", vA, vB, vC);
			snprintf (str, sizeof (str), " v%i, v%i, %#x", vA, vB, vC);
			snprintf (str, sizeof (str), " v%i, v%i, %#x", vA, vB, vC);
			//snprintf (str, sizeof (str), " %i", vA*2); // vA : word -> byte
			//snprintf (str, sizeof (str), " v%i, %i", vA, vB);
			//snprintf (str, sizeof (str), " %#08x", vA*2); // vA: word -> byte
			//snprintf (str, sizeof (str), " v%i, v%i, %i", vA, vB, vC);
				snprintf (str, sizeof (str), " {v%i}", buf[4] & 0x0f);
				snprintf (str, sizeof (str), " {v%i, v%i}", buf[4] & 0x0f, (buf[4] & 0xf0) >> 4);
				snprintf (str, sizeof (str), " {v%i, v%i, v%i}", buf[4] & 0x0f, (buf[4] & 0xf0) >> 4, buf[5] & 0x0f);
				snprintf (str, sizeof (str), " {v%i, v%i, v%i, v%i}", buf[4] & 0x0f,
				snprintf (str, sizeof (str), " {}");
			snprintf (str, sizeof (str), ", [%04x]", vB);
			snprintf (str, sizeof (str), " {v%i..v%i}, [%04x]", vC, vC + vA - 1, vB);
				snprintf (str, sizeof (str), " {v%i}", buf[4] & 0x0f);
				snprintf (str, sizeof (str), " {v%i, v%i}", buf[4] & 0x0f, (buf[4] & 0xf0) >> 4);
				snprintf (str, sizeof (str), " {v%i, v%i, v%i}", buf[4] & 0x0f,
				snprintf (str, sizeof (str), " {v%i, v%i, v%i, v%i}", buf[4] & 0x0f,
				snprintf (str, sizeof (str), " {}");
			snprintf (str, sizeof (str), ", [%04x]", vB);
					snprintf (str, sizeof (str), " v%i, string+%i", vA, vB);
					snprintf (str, sizeof (str), " v%i, 0x%"PFMT64x, vA, offset);
					snprintf (str, sizeof (str), " v%i, class+%i", vA, vB);
					snprintf (str, sizeof (str), " v%i, %s", vA, flag_str);
					snprintf (str, sizeof (str), " v%i, field+%i", vA, vB);
					snprintf (str, sizeof (str), " v%i, %s", vA, flag_str);
				snprintf (str, sizeof (str), " v%i, v%i, [obj+%04x]", vA, vB, vC);
				snprintf (str, sizeof (str), " v%i, v%i, [0x%"PFMT64x"]", vA, vB, offset);
				snprintf (str, sizeof (str), " v%i, thing+%i", vA, vB);
				snprintf (str, sizeof (str), " v%i, 0x%"PFMT64x, vA, offset);
					snprintf (str, sizeof (str), " v%i, v%i, %s", vA, vB, flag_str);
					snprintf (str, sizeof (str), " v%i, v%i, class+%i", vA, vB, vC);
					snprintf (str, sizeof (str), " v%i, v%i, %s", vA, vB, flag_str);
					snprintf (str, sizeof (str), " v%i, v%i, field+%i", vA, vB, vC);
				snprintf (str, sizeof (str), " v%i, string+%i", vA, vB);
				snprintf (str, sizeof (str), " v%i, 0x%"PFMT64x, vA, offset);
					snprintf (str, sizeof (str), " {v%i..v%i}, %s", vC, vC + vA - 1, flag_str);
					snprintf (str, sizeof (str), " {v%i..v%i}, class+%i", vC, vC + vA - 1, vB);
					snprintf (str, sizeof (str), " {v%i..v%i}, %s", vC, vC + vA - 1, flag_str);
					snprintf (str, sizeof (str), " {v%i..v%i}, method+%i", vC, vC + vA - 1, vB);
					snprintf (str, sizeof (str), " {v%i}", buf[4] & 0x0f);
					snprintf (str, sizeof (str), " {v%i, v%i}", buf[4] & 0x0f, (buf[4] & 0xf0) >> 4);
					snprintf (str, sizeof (str), " {v%i, v%i, v%i}", buf[4] & 0x0f,
					snprintf (str, sizeof (str), " {v%i, v%i, v%i, v%i}", buf[4] & 0x0f,
					snprintf (str, sizeof (str), " {v%i, v%i, v%i, v%i, v%i}", buf[4] & 0x0f,
					snprintf (str, sizeof (str), " {}");
					snprintf (str, sizeof (str), ", %s ; 0x%x", flag_str, vB);
					snprintf (str, sizeof (str), ", class+%i", vB);
					snprintf (str, sizeof (str), ", %s ; 0x%x", flag_str, vB);
					snprintf (str, sizeof (str), ", method+%i", vB);