CVE-2022-0521 (C, published 2022-02-08T21:15Z)
Description: value: Access of Memory Location After End of Buffer in GitHub repository radareorg/radare2 prior to 5.6.2.
Severity: MEDIUM (CVSS v3 base score: 7.1)
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/radareorg/radare2
Files changed:
shlr/java/class.c
Commit message: Improve boundary checks to fix oobread segfaults ##crash

* Reported by Cen Zhang via huntr.dev
* Reproducer: bins/fuzzed/javaoob-havoc.class


Vulnerable code:
	RBinJavaAttrInfo *attr = NULL;
	attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
	offset += 6;
	if (buf_offset + offset + 8 > sz) {
		eprintf ("Invalid amount of inner classes\n");
	if (attr == NULL) {
		// TODO eprintf
		return attr;
		if (buf_offset + offset + 8 > sz) {
	RBinJavaAttrInfo *attr;
	if (!buffer || sz < 1) {
	attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
	if (!sz) {
	if (!attr) {
		return NULL;
	attr->type = R_BIN_JAVA_ATTR_TYPE_SOURCE_FILE_ATTR;
	// if (buffer + offset > buffer + sz) return NULL;
	attr->info.source_file_attr.sourcefile_idx = R_BIN_JAVA_USHORT (buffer, offset);
	offset += 2;
	attr->size = offset;
	// IFDBG r_bin_java_print_source_code_file_attr_summary(attr);
	ut64 offset = 0;
	offset += 6;
	attr->size = offset;
	if (!se) {
		return NULL;
	}
	se->tag = type;
	if (se->tag == R_BIN_JAVA_STACKMAP_OBJECT) {
		se->info.obj_val_cp_idx = (ut16) value;
	} else if (se->tag == R_BIN_JAVA_STACKMAP_UNINIT) {
		/*if (bin->offset_sz == 4) {
		se->info.uninit_offset = value;
		} else {
		se->info.uninit_offset = (ut16) value;
		}*/
		se->info.uninit_offset = (ut16) value;
	IFDBG eprintf("r_bin_java_stack_map_table_attr_new: New stack map allocated.\n");
	RBinJavaAttrInfo *attr = NULL;
	attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
	RBinJavaAnnotation *annotation = NULL;
	annotation = R_NEW0 (RBinJavaAnnotation);
	ut64 sz = 0;
	if (evp == NULL) {
		return sz;
	}
	// evp->element_name_idx = r_bin_java_read_short(bin, bin->b->cur);
	sz += 2;
	// evp->value = r_bin_java_element_value_new (bin, offset+2);
	if (evp->value) {
	if (buf_offset + 8 > sz) {

Fixed code:
	if (sz < 8) {
		return NULL;
	}
	if (sz < 8) {
	RBinJavaAttrInfo *attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
	if (!attr) {
		return NULL;
	offset += 6;
		if (offset + 8 > sz) {
	if (sz < 8) {
		return NULL;
	}
	if (!bin || !buffer || sz < 8) {
	RBinJavaAttrInfo *attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
	if (sz < 8) {
		return NULL;
	}
	if (!sz || sz == UT64_MAX) {
		return NULL;
	}
#if 0
	/// XXX this breaks tests
	if (sz < 8) {
#endif
	if (attr) {
		attr->type = R_BIN_JAVA_ATTR_TYPE_SOURCE_FILE_ATTR;
		attr->info.source_file_attr.sourcefile_idx = R_BIN_JAVA_USHORT (buffer, offset);
		offset += 2;
		attr->size = offset;
		// IFDBG r_bin_java_print_source_code_file_attr_summary(attr);
	if (sz < 8) {
		return NULL;
	}
	attr->size = 6;
	if (se) {
		se->tag = type;
		if (se->tag == R_BIN_JAVA_STACKMAP_OBJECT) {
			se->info.obj_val_cp_idx = (ut16) value;
		} else if (se->tag == R_BIN_JAVA_STACKMAP_UNINIT) {
			se->info.uninit_offset = (ut16) value;
		}
	if (sz < 8) {
		return NULL;
	}
	if (sz < 8) {
		return NULL;
	}
	if (sz < 8) {
		return NULL;
	}
	IFDBG eprintf ("r_bin_java_stack_map_table_attr_new: New stack map allocated.\n");
	if (sz < 8) {
		return NULL;
	}
	RBinJavaAttrInfo *attr = r_bin_java_default_attr_new (bin, buffer, sz, buf_offset);
	if (sz < 8) {
		return NULL;
	}
	RBinJavaAnnotation *annotation = R_NEW0 (RBinJavaAnnotation);
	ut64 sz = 2;
	if (evp && evp->value) {
		// evp->element_name_idx = r_bin_java_read_short(bin, bin->b->cur);
		// evp->value = r_bin_java_element_value_new (bin, offset+2);
	if (sz < 8) {
		return NULL;
	}
	if (sz < 8) {