CVE-2022-1451: Out-of-bounds Read (CWE-125)
value: Out-of-bounds Read in r_bin_java_constant_value_attr_new function in GitHub repository radareorg/radare2 prior to 5.7.0. The bug causes the program reads data past the end 2f the intented buffer. Typically, this can allow attackers to read sensitive information from other memory locations or cause a crash. More details see [CWE-125: Out-of-bounds read](https://cwe.mitre.org/data/definitions/125.html).
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-04-24T21:15Z
Repository: https://github.com/radareorg/radare2
Language: C
Files changed: shlr/java/class.c
Commit date: 2022-04-24 21:53:13 +0200
Commit message: Fix oobread crash in java parser ##crash

* Reported by @bet4it via @huntrdev
* BountyID: 229a2e0d-9e5c-402f-9a24-57fa2eb1aaa7
* Reproducer: poc4java

Diff: diff --git a/shlr/java/class.c b/shlr/java/class.c
index 2acec6801834..80919af8ecbd 100644
--- a/shlr/java/class.c
+++ b/shlr/java/class.c
@@ -1955,14 +1955,14 @@ R_API RBinJavaAttrInfo *r_bin_java_get_attr_from_field(RBinJavaField *field, R_B
 	}
 	return attr;
 }
 
 R_API ut8 *r_bin_java_get_attr_buf(RBinJavaObj *bin, ut64 sz, const ut64 offset, const ut8 *buf, const ut64 len) {
-	ut8 *attr_buf = NULL;
+	// XXX this pending is wrong and too expensive
 	int pending = len - offset;
 	const ut8 *a_buf = offset + buf;
-	attr_buf = (ut8 *) calloc (pending + 1, 1);
+	ut8 *attr_buf = (ut8 *) calloc (pending + 1, 1);
 	if (!attr_buf) {
 		eprintf ("Unable to allocate enough bytes (0x%04"PFMT64x
 			") to read in the attribute.\n", sz);
 		return attr_buf;
 	}
@@ -3557,11 +3557,13 @@ R_API RBinJavaAttrInfo *r_bin_java_code_attr_new(RBinJavaObj *bin, ut8 *buffer,
 R_API RBinJavaAttrInfo *r_bin_java_constant_value_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
 	ut64 offset = 6;
 	RBinJavaAttrInfo *attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
 	if (attr) {
 		attr->type = R_BIN_JAVA_ATTR_TYPE_CONST_VALUE_ATTR;
-		attr->info.constant_value_attr.constantvalue_idx = R_BIN_JAVA_USHORT (buffer, offset);
+		if (offset + 4 < sz) {
+			attr->info.constant_value_attr.constantvalue_idx = R_BIN_JAVA_USHORT (buffer, offset);
+		}
 		offset += 2;
 		attr->size = offset;
 	}
 	// IFDBG r_bin_java_print_constant_value_attr_summary(attr);
 	return attr;
@@ -7077,13 +7079,15 @@ R_API ut64 r_bin_java_rtv_annotations_attr_calc_size(RBinJavaAttrInfo *attr) {
 	return size;
 }
 
 R_API RBinJavaAttrInfo *r_bin_java_rti_annotations_attr_new(RBinJavaObj *bin, ut8 *buffer, ut64 sz, ut64 buf_offset) {
 	ut32 i = 0;
-	RBinJavaAttrInfo *attr = NULL;
 	ut64 offset = 0;
-	attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
+	if (buf_offset + 32 >= sz) {
+		return NULL;
+	}
+	RBinJavaAttrInfo *attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
 	offset += 6;
 	if (attr) {
 		attr->type = R_BIN_JAVA_ATTR_TYPE_RUNTIME_INVISIBLE_ANNOTATION_ATTR;
 		attr->info.annotation_array.num_annotations = R_BIN_JAVA_USHORT (buffer, offset);
 		offset += 2;

Vulnerable code: 	ut8 *attr_buf = NULL;
	attr_buf = (ut8 *) calloc (pending + 1, 1);
		attr->info.constant_value_attr.constantvalue_idx = R_BIN_JAVA_USHORT (buffer, offset);
	RBinJavaAttrInfo *attr = NULL;
	attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
Fixed code: 	// XXX this pending is wrong and too expensive
	ut8 *attr_buf = (ut8 *) calloc (pending + 1, 1);
		if (offset + 4 < sz) {
			attr->info.constant_value_attr.constantvalue_idx = R_BIN_JAVA_USHORT (buffer, offset);
		}
	if (buf_offset + 32 >= sz) {
		return NULL;
	}
	RBinJavaAttrInfo *attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);