CVE-2022-1714: Out-of-bounds Read (CWE-125)
value: Out-of-bounds Read 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.
CWE description: The product reads data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 7.1
Published: 2022-05-13T15:15Z
Repository: https://github.com/radareorg/radare2
Language: C
Files changed: libr/anal/p/anal_msp430.c, libr/bin/format/elf/elf.c
Commit date: 2022-05-13 16:11:37 +0200
Commit message: Fix 4 byte oobread in msp430 disassembler ##crash

* Only crashes with asan builds
* Add missing =SN register
* Reported by cnitlrt via huntrdev
* BountyID: 1c22055b-b015-47a8-a57b-4982978751d0

Diff: diff --git a/libr/anal/p/anal_msp430.c b/libr/anal/p/anal_msp430.c
index fbb51828a402..d8298db57867 100644
--- a/libr/anal/p/anal_msp430.c
+++ b/libr/anal/p/anal_msp430.c
@@ -8,21 +8,17 @@
 #include <r_util.h>
 
 #include "../arch/msp430/msp430_disas.h"
 
 static int msp430_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int len, RAnalOpMask mask) {
-	int ret;
-	struct msp430_cmd cmd;
-
-	memset (&cmd, 0, sizeof (cmd));
-	//op->id = ???;
+	struct msp430_cmd cmd = {0};
 	op->size = -1;
 	op->nopcode = 1;
 	op->type = R_ANAL_OP_TYPE_UNK;
 	op->family = R_ANAL_OP_FAMILY_CPU;
 
-	ret = op->size = msp430_decode_command (buf, len, &cmd);
+	int ret = op->size = msp430_decode_command (buf, len, &cmd);
 	if (mask & R_ANAL_OP_MASK_DISASM) {
 		if (ret < 1) {
 			op->mnemonic = strdup ("invalid");
 		} else if (ret > 0) {
 			if (cmd.operands[0]) {
@@ -57,11 +53,13 @@ static int msp430_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int le
 			op->type = R_ANAL_OP_TYPE_PUSH;
 			break;
 		case MSP430_CALL:
 			op->type = R_ANAL_OP_TYPE_CALL;
 			op->fail = addr + op->size;
-			op->jump = r_read_at_le16 (buf, 2);
+			if (len > 4) {
+				op->jump = r_read_at_le16 (buf, 2);
+			}
 			break;
 		case MSP430_RETI:
 			op->type = R_ANAL_OP_TYPE_RET;
 			break;
 		}
@@ -109,10 +107,11 @@ static int msp430_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *buf, int le
 
 static bool set_reg_profile(RAnal *anal) {
 	const char *p = \
 		"=PC	pc\n"
 		"=SP	sp\n"
+		"=SN	r0\n"
 		// this is the "new" ABI, the old was reverse order
 		"=A0	r12\n"
 		"=A1	r13\n"
 		"=A2	r14\n"
 		"=A3	r15\n"
diff --git a/libr/bin/format/elf/elf.c b/libr/bin/format/elf/elf.c
index 9239d59e45c0..40f6566d49ed 100644
--- a/libr/bin/format/elf/elf.c
+++ b/libr/bin/format/elf/elf.c
@@ -122,11 +122,11 @@ static bool __is_valid_ident(ELFOBJ *bin) {
 static bool init_ehdr(ELFOBJ *bin) {
 	ut8 e_ident[EI_NIDENT];
 	ut8 ehdr[sizeof (Elf_(Ehdr))] = {0};
 	int i, len;
 	if (r_buf_read_at (bin->b, 0, e_ident, EI_NIDENT) == -1) {
-		R_LOG_ERROR ("read (magic)");
+		R_LOG_DEBUG ("read (magic)");
 		return false;
 	}
 	sdb_set (bin->kv, "elf_type.cparse", "enum elf_type { ET_NONE=0, ET_REL=1,"
 			" ET_EXEC=2, ET_DYN=3, ET_CORE=4, ET_LOOS=0xfe00, ET_HIOS=0xfeff,"
 			" ET_LOPROC=0xff00, ET_HIPROC=0xffff };", 0);
@@ -186,11 +186,11 @@ static bool init_ehdr(ELFOBJ *bin) {
 #endif
 	bin->endian = (e_ident[EI_DATA] == ELFDATA2MSB)? 1: 0;
 	memset (&bin->ehdr, 0, sizeof (Elf_(Ehdr)));
 	len = r_buf_read_at (bin->b, 0, ehdr, sizeof (ehdr));
 	if (len < 32) { // tinyelf != sizeof (Elf_(Ehdr))) {
-		R_LOG_ERROR ("read (ehdr)");
+		R_LOG_DEBUG ("read (ehdr)");
 		return false;
 	}
 	// XXX no need to check twice
 	memcpy (&bin->ehdr.e_ident, ehdr, 16);
 	if (!__is_valid_ident (bin)) {
@@ -255,11 +255,11 @@ static bool read_phdr(ELFOBJ *bin, bool linux_kernel_hack) {
 		ut8 phdr[sizeof (Elf_(Phdr))] = {0};
 		int j = 0;
 		const size_t rsize = bin->ehdr.e_phoff + i * sizeof (Elf_(Phdr));
 		int len = r_buf_read_at (bin->b, rsize, phdr, sizeof (Elf_(Phdr)));
 		if (len < 1) {
-			R_LOG_ERROR ("read (phdr)");
+			R_LOG_DEBUG ("read (phdr)");
 			R_FREE (bin->phdr);
 			return false;
 		}
 		bin->phdr[i].p_type = READ32 (phdr, j);
 		if (bin->phdr[i].p_type == PT_PHDR) {
@@ -395,11 +395,11 @@ static int init_shdr(ELFOBJ *bin) {
 
 	for (i = 0; i < bin->ehdr.e_shnum; i++) {
 		j = 0;
 		len = r_buf_read_at (bin->b, bin->ehdr.e_shoff + i * sizeof (Elf_(Shdr)), shdr, sizeof (Elf_(Shdr)));
 		if (len < 1) {
-			R_LOG_ERROR ("read (shdr) at 0x%" PFMT64x, (ut64) bin->ehdr.e_shoff);
+			R_LOG_DEBUG ("read (shdr) at 0x%" PFMT64x, (ut64) bin->ehdr.e_shoff);
 			R_FREE (bin->shdr);
 			return false;
 		}
 		bin->shdr[i].sh_name = READ32 (shdr, j);
 		bin->shdr[i].sh_type = READ32 (shdr, j);
@@ -473,11 +473,11 @@ static int init_strtab(ELFOBJ *bin) {
 		return false;
 	}
 	int res = r_buf_read_at (bin->b, bin->shstrtab_section->sh_offset, (ut8*)bin->shstrtab,
 		bin->shstrtab_section->sh_size);
 	if (res < 1) {
-		R_LOG_ERROR ("read (shstrtab) at 0x%" PFMT64x, (ut64) bin->shstrtab_section->sh_offset);
+		R_LOG_DEBUG ("read (shstrtab) at 0x%" PFMT64x, (ut64) bin->shstrtab_section->sh_offset);
 		R_FREE (bin->shstrtab);
 		return false;
 	}
 	bin->shstrtab[bin->shstrtab_section->sh_size] = '\0';
 
@@ -968,11 +968,11 @@ static Sdb *store_versioninfo_gnu_verdef(ELFOBJ *bin, Elf_(Shdr) *shdr, int sz)
 	if (shdr->sh_size < sizeof (Elf_(Verdef)) || shdr->sh_size < sizeof (Elf_(Verdaux))) {
 		return false;
 	}
 	Elf_(Verdef) *defs = calloc (shdr->sh_size, 1);
 	if (!defs) {
-		R_LOG_ERROR ("Cannot allocate memory (Check Elf_(Verdef))");
+		R_LOG_DEBUG ("Cannot allocate memory (Check Elf_(Verdef))");
 		return false;
 	}
 	if (bin->shstrtab && shdr->sh_name < bin->shstrtab_size) {
 		section_name = &bin->shstrtab[shdr->sh_name];
 	}
@@ -1796,11 +1796,11 @@ ut64 Elf_(r_bin_elf_get_init_offset)(ELFOBJ *bin) {
 	ut8 buf[128];
 	if (!bin || entry == UT64_MAX) {
 		return UT64_MAX;
 	}
 	if (r_buf_read_at (bin->b, entry + 16, buf, sizeof (buf)) < 1) {
-		R_LOG_ERROR ("read (init_offset)");
+		R_LOG_DEBUG ("read (init_offset)");
 		return 0;
 	}
 	if (buf[0] == 0x68) { // push // x86 only
 		ut64 addr;
 		memmove (buf, buf + 1, 4);

Vulnerable code: 	int ret;
	struct msp430_cmd cmd;

	memset (&cmd, 0, sizeof (cmd));
	//op->id = ???;
	ret = op->size = msp430_decode_command (buf, len, &cmd);
			op->jump = r_read_at_le16 (buf, 2);
		R_LOG_ERROR ("read (magic)");
		R_LOG_ERROR ("read (ehdr)");
			R_LOG_ERROR ("read (phdr)");
			R_LOG_ERROR ("read (shdr) at 0x%" PFMT64x, (ut64) bin->ehdr.e_shoff);
		R_LOG_ERROR ("read (shstrtab) at 0x%" PFMT64x, (ut64) bin->shstrtab_section->sh_offset);
		R_LOG_ERROR ("Cannot allocate memory (Check Elf_(Verdef))");
		R_LOG_ERROR ("read (init_offset)");
Fixed code: 	struct msp430_cmd cmd = {0};
	int ret = op->size = msp430_decode_command (buf, len, &cmd);
			if (len > 4) {
				op->jump = r_read_at_le16 (buf, 2);
			}
		"=SN	r0\n"
		R_LOG_DEBUG ("read (magic)");
		R_LOG_DEBUG ("read (ehdr)");
			R_LOG_DEBUG ("read (phdr)");
			R_LOG_DEBUG ("read (shdr) at 0x%" PFMT64x, (ut64) bin->ehdr.e_shoff);
		R_LOG_DEBUG ("read (shstrtab) at 0x%" PFMT64x, (ut64) bin->shstrtab_section->sh_offset);
		R_LOG_DEBUG ("Cannot allocate memory (Check Elf_(Verdef))");
		R_LOG_DEBUG ("read (init_offset)");