CVE-2017-6197 (published 2017-02-24T04:59Z)

The r_read_* functions in libr/include/r_endian.h in radare2 1.2.1 allow remote attackers to cause a denial of service (NULL pointer dereference and application crash) via a crafted binary file, as demonstrated by the r_read_le32 function.

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.0/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H)

Weakness information:
cwe_id: CWE-476
cwe_name: NULL Pointer Dereference
description: The product dereferences a pointer that it expects to be valid but is NULL.
extended_description: 
            
            
            
         
         

Fix information:
repo_url: https://github.com/radare/radare2
commit_details: repo_url: https://github.com/radare/radare2
author: pancake
author_date: 2017-02-20 12:08:06+01:00
msg: Fix #6816 - null deref in r_read_*
repository: repo_url: https://github.com/radare/radare2
repo_name: radareorg/radare2
description: UNIX-like reverse engineering framework and command-line toolset
repo_language: C
owner: radare
file_changes: filename: uncrustify.cfg
change_type: ModificationType.MODIFY
diff: @@ -483,7 +483,7 @@ nl_before_block_comment         = 0
 nl_before_c_comment             = 0
 nl_before_cpp_comment           = 0
 nl_after_multiline_comment      = false
-nl_after_label_colon            = force
+nl_after_label_colon            = true
 nl_after_struct                 = 0
 nl_before_class                 = 0
 nl_after_class                  = 0

programming_language: Haskell
filename: bin_dex.c
change_type: ModificationType.MODIFY
diff: @@ -1322,7 +1322,7 @@ static void parse_class(RBinFile *binfile, RBinDexObj *bin, RBinDexClass *c,
 	    c->interfaces_offset <
 		    bin->header.data_offset + bin->header.data_size) {
 		p = r_buf_get_at (binfile->buf, c->interfaces_offset, NULL);
-		int types_list_size = r_read_le32(p);
+		int types_list_size = r_read_le32 (p);
 		if (types_list_size < 0 || types_list_size >= bin->header.types_size ) {
 			return;
 		}

programming_language: C
filename: r_endian.h
change_type: ModificationType.MODIFY
diff: @@ -8,6 +8,9 @@ extern "C" {
 /* Endian agnostic functions working on single byte. */
 
 static inline ut8 r_read_ble8(const void *src) {
+	if (!src) {
+		return UT8_MAX;
+	}
 	return *(ut8 *)src;
 }
 
@@ -114,6 +117,9 @@ static inline void r_write_at_be64(void *dest, ut64 val, size_t offset) {
 /* Little Endian functions. */
 
 static inline ut8 r_read_le8(const void *src) {
+	if (!src) {
+		return UT8_MAX;
+	}
 	return r_read_ble8 (src);
 }
 
@@ -130,11 +136,17 @@ static inline void r_write_at_le8(void *dest, ut8 val, size_t offset) {
 }
 
 static inline ut16 r_read_le16(const void *src) {
+	if (!src) {
+		return UT16_MAX;
+	}
 	const ut8 *s = (const ut8*)src;
 	return (((ut16)s[1]) << 8) | (((ut16)s[0]) << 0);
 }
 
 static inline ut16 r_read_at_le16(const void *src, size_t offset) {
+	if (!src) {
+		return UT16_MAX;
+	}
 	const ut8 *s = (const ut8*)src + offset;
 	return r_read_le16 (s);
 }
@@ -157,12 +169,18 @@ static inline void r_write_le24(void *_dest, ut32 val) {
 }
 
 static inline ut32 r_read_le32(const void *src) {
+	if (!src) {
+		return UT32_MAX;
+	}
 	const ut8 *s = (const ut8*)src;
 	return (((ut32)s[3]) << 24) | (((ut32)s[2]) << 16) |
 		(((ut32)s[1]) << 8) | (((ut32)s[0]) << 0);
 }
 
 static inline ut32 r_read_at_le32(const void *src, size_t offset) {
+	if (!src) {
+		return UT32_MAX;
+	}
 	const ut8 *s = (const ut8*)src + offset;
 	return r_read_le32 (s);
 }
@@ -426,6 +444,7 @@ static inline int UT8_SUB(ut8 *r, ut8 a, ut8 b) {
 	}
 	return 1;
 }
+
 #ifdef __cplusplus
 }
 #endif

programming_language: C