CVE-2018-14017 (published 2018-07-12T20:29Z)

The r_bin_java_annotation_new function in shlr/java/class.c in radare2 2.7.0 allows remote attackers to cause a denial of service (heap-based buffer over-read and application crash) via a crafted .class file because of missing input validation in r_bin_java_line_number_table_attr_new.

Severity: MEDIUM
CVSS v2 base score: 4.3 (AV:N/AC:M/Au:N/C:N/I:N/A:P)
CVSS v3 base score: 5.5, MEDIUM (CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/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/radareorg/radare2
commit_details: repo_url: https://github.com/radareorg/radare2
author: radare
author_date: 2018-06-27 13:56:59+02:00
msg: Fix #10498 - Fix crash in fuzzed java files (#10511)
repository: repo_url: https://github.com/radareorg/radare2
repo_name: radareorg/radare2
description: UNIX-like reverse engineering framework and command-line toolset
repo_language: C
owner: radareorg
file_changes: filename: class.c
change_type: ModificationType.MODIFY
diff: @@ -2070,11 +2070,9 @@ R_API RBinJavaAttrInfo *r_bin_java_read_next_attr(RBinJavaObj *bin, const ut64 o
 
 R_API RBinJavaAttrInfo *r_bin_java_read_next_attr_from_buffer(ut8 *buffer, st64 sz, st64 buf_offset) {
 	RBinJavaAttrInfo *attr = NULL;
-	char *name = NULL;
 	ut64 offset = 0;
 	ut16 name_idx;
 	st64 nsz;
-	RBinJavaAttrMetas *type_info = NULL;
 
 	if (!buffer || ((int) sz) < 4 || buf_offset < 0) {
 		eprintf ("r_bin_Java_read_next_attr_from_buffer: invalid buffer size %d\n", (int) sz);
@@ -2084,12 +2082,13 @@ R_API RBinJavaAttrInfo *r_bin_java_read_next_attr_from_buffer(ut8 *buffer, st64
 	offset += 2;
 	nsz = R_BIN_JAVA_UINT (buffer, offset);
 	offset += 4;
-	name = r_bin_java_get_utf8_from_bin_cp_list (R_BIN_JAVA_GLOBAL_BIN, name_idx);
+
+	char *name = r_bin_java_get_utf8_from_bin_cp_list (R_BIN_JAVA_GLOBAL_BIN, name_idx);
 	if (!name) {
 		name = strdup ("unknown");
 	}
 	IFDBG eprintf("r_bin_java_read_next_attr: name_idx = %d is %s\n", name_idx, name);
-	type_info = r_bin_java_get_attr_type_by_name (name);
+	RBinJavaAttrMetas *type_info = r_bin_java_get_attr_type_by_name (name);
 	if (type_info) {
 		IFDBG eprintf("Typeinfo: %s, was %s\n", type_info->name, name);
 		// printf ("SZ %d %d %d\n", nsz, sz, buf_offset);
@@ -3432,7 +3431,7 @@ R_API RBinJavaAttrInfo *r_bin_java_code_attr_new(ut8 *buffer, ut64 sz, ut64 buf_
 	// BUG: possible unsigned integer overflow here
 	attr->info.code_attr.code_offset = buf_offset + offset;
 	attr->info.code_attr.code = (ut8 *) malloc (attr->info.code_attr.code_length);
-	if (attr->info.code_attr.code == NULL) {
+	if (!attr->info.code_attr.code) {
 		eprintf ("Handling Code Attributes: Unable to allocate memory "
 			"(%u bytes) for a code.\n", attr->info.code_attr.code_length);
 		return attr;
@@ -3777,10 +3776,6 @@ R_API RBinJavaAttrInfo *r_bin_java_line_number_table_attr_new(ut8 *buffer, ut64
 
 	ut32 linenum_len = attr->info.line_number_table_attr.line_number_table_length;
 	RList *linenum_list = attr->info.line_number_table_attr.line_number_table;
-	if (linenum_len > sz) {
-		free (attr);
-		return NULL;
-	}
 	for (i = 0; i < linenum_len; i++) {
 		curpos = buf_offset + offset;
 		// printf ("%llx %llx \n", curpos, sz);
@@ -3789,6 +3784,10 @@ R_API RBinJavaAttrInfo *r_bin_java_line_number_table_attr_new(ut8 *buffer, ut64
 		if (!lnattr) {
 			break;
 		}
+		// wtf it works
+		if (offset - 2 > sz) {
+			break;
+		}
 		lnattr->start_pc = R_BIN_JAVA_USHORT (buffer, offset);
 		offset += 2;
 		lnattr->line_number = R_BIN_JAVA_USHORT (buffer, offset);
@@ -3982,6 +3981,10 @@ R_API RBinJavaAttrInfo *r_bin_java_local_variable_type_table_attr_new(ut8 *buffe
 			perror ("calloc");
 			break;
 		}
+		if (offset + 10 > sz) {
+			eprintf ("oob");
+			break;
+		}
 		lvattr->start_pc = R_BIN_JAVA_USHORT (buffer, offset);
 		offset += 2;
 		lvattr->length = R_BIN_JAVA_USHORT (buffer, offset);

programming_language: C++