CVE-2017-6197: NULL Pointer Dereference (CWE-476)
value: 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.
CWE description: The product dereferences a pointer that it expects to be valid but is NULL.
CVSS v3 base score: 5.5
Published: 2017-02-24T04:59Z
Repository: https://github.com/radare/radare2
Language: C
Files changed: doc/uncrustify.cfg, libr/bin/p/bin_dex.c, libr/include/r_endian.h
Commit date: 2017-02-20 12:08:06 +0100
Commit message: Fix #6816 - null deref in r_read_*

Diff: diff --git a/doc/uncrustify.cfg b/doc/uncrustify.cfg
index df31ff1f09b..42810ad098b 100644
--- a/doc/uncrustify.cfg
+++ b/doc/uncrustify.cfg
@@ -481,11 +481,11 @@ nl_after_func_body_class        = 0
 nl_after_func_body_one_liner    = 0
 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
 nl_before_access_spec           = 0
 nl_after_access_spec            = 0
diff --git a/libr/bin/p/bin_dex.c b/libr/bin/p/bin_dex.c
index 2923ba73287..601b28a5d71 100644
--- a/libr/bin/p/bin_dex.c
+++ b/libr/bin/p/bin_dex.c
@@ -1320,11 +1320,11 @@ static void parse_class(RBinFile *binfile, RBinDexObj *bin, RBinDexClass *c,
 	if (c->interfaces_offset > 0 &&
 	    bin->header.data_offset < c->interfaces_offset &&
 	    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;
 		}
 		for (z = 0; z < types_list_size; z++) {
 			int t = r_read_le16 (p + 4 + z * 2);
diff --git a/libr/include/r_endian.h b/libr/include/r_endian.h
index 855f9e0dcd1..1a2afc603aa 100644
--- a/libr/include/r_endian.h
+++ b/libr/include/r_endian.h
@@ -6,10 +6,13 @@ extern "C" {
 #endif
 
 /* Endian agnostic functions working on single byte. */
 
 static inline ut8 r_read_ble8(const void *src) {
+	if (!src) {
+		return UT8_MAX;
+	}
 	return *(ut8 *)src;
 }
 
 static inline ut8 r_read_at_ble8(const void *src, size_t offset) {
 	return r_read_ble8 (((const ut8*)src) + offset);
@@ -112,10 +115,13 @@ 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);
 }
 
 static inline ut8 r_read_at_le8(const void *src, size_t offset) {
 	return r_read_at_ble8 (src, offset);
@@ -128,15 +134,21 @@ static inline void r_write_le8(void *dest, ut8 val) {
 static inline void r_write_at_le8(void *dest, ut8 val, size_t offset) {
 	r_write_at_ble8 (dest, val, 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);
 }
 
 static inline void r_write_le16(void *dest, ut16 val) {
@@ -155,16 +167,22 @@ static inline void r_write_le24(void *_dest, ut32 val) {
 	r_write_le8 (dest++, val >> 8);
 	r_write_le8 (dest,   val >> 16);
 }
 
 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);
 }
 
 static inline void r_write_le32(void *dest, ut32 val) {
@@ -424,10 +442,11 @@ static inline int UT8_SUB(ut8 *r, ut8 a, ut8 b) {
 	if (r) {
 		*r = a - b;
 	}
 	return 1;
 }
+
 #ifdef __cplusplus
 }
 #endif
 
 #endif

Vulnerable code: nl_after_label_colon            = force
		int types_list_size = r_read_le32(p);
Fixed code: nl_after_label_colon            = true
		int types_list_size = r_read_le32 (p);
	if (!src) {
		return UT8_MAX;
	}
	if (!src) {
		return UT8_MAX;
	}
	if (!src) {
		return UT16_MAX;
	}
	if (!src) {
		return UT16_MAX;
	}
	if (!src) {
		return UT32_MAX;
	}
	if (!src) {
		return UT32_MAX;
	}