Vulnerability: The relocs function in libr/bin/p/bin_bflt.c in radare2 1.2.1 allows remote attackers to cause a denial of service (heap-based buffer overflow and application crash) or possibly have unspecified other impact via a crafted binary file.
Vulnerability ID: CVE-2017-6194
CWE: CWE-119
Severity score: 6.4
Project: https://github.com/radare/radare2
Published: 2017-04-03
File: libr/bin/p/bin_bflt.c
Commit message: Fix #6829 oob write because of using wrong struct
Commit author: alvarofe

Vulnerable version (before fix):
 static void *load_bytes(RBinFile *arch, const ut8 *buf, ut64 sz, ut64 loaddr, Sd 		return NULL; 	} 	RBuffer *tbuf = r_buf_new (); 	r_buf_set_bytes (tbuf, buf, sz); 	struct r_bin_bflt_obj *res = r_bin_bflt_new_buf (tbuf); 	r_buf_free (tbuf); static void __patch_reloc(RBuffer *buf, ut32 addr_to_patch, ut32 data_offset) { 	r_buf_write_at (buf, addr_to_patch, (void *)val, sizeof (val)); }  static int search_old_relocation(struct reloc_struct_t *reloc_table, ut32 addr_to_patch, int n_reloc) { 	int i; 	for (i = 0; i < n_reloc; i++) { 		if (addr_to_patch == reloc_table[i].data_offset) { static RList *relocs(RBinFile *arch) { 			if (amount < n_got || amount > UT32_MAX) { 				goto out_error; 			} 			struct reloc_struct_t *got_table = calloc (1, n_got * sizeof (ut32)); 			if (got_table) { 				ut32 offset = 0; 				for (i = 0; i < n_got ; offset += 4, i++) {

Fixed version (after fix):
 static void *load_bytes(RBinFile *arch, const ut8 *buf, ut64 sz, ut64 loaddr, Sd 		return NULL; 	} 	RBuffer *tbuf = r_buf_new (); 	if (!tbuf) { 		return NULL; 	} 	r_buf_set_bytes (tbuf, buf, sz); 	struct r_bin_bflt_obj *res = r_bin_bflt_new_buf (tbuf); 	r_buf_free (tbuf); static void __patch_reloc(RBuffer *buf, ut32 addr_to_patch, ut32 data_offset) { 	r_buf_write_at (buf, addr_to_patch, (void *)val, sizeof (val)); }  static int search_old_relocation (struct reloc_struct_t *reloc_table, 				  ut32 addr_to_patch, int n_reloc) { 	int i; 	for (i = 0; i < n_reloc; i++) { 		if (addr_to_patch == reloc_table[i].data_offset) { static RList *relocs(RBinFile *arch) { 			if (amount < n_got || amount > UT32_MAX) { 				goto out_error; 			} 			struct reloc_struct_t *got_table = calloc ( 				1, n_got * sizeof (struct reloc_struct_t)); 			if (got_table) { 				ut32 offset = 0; 				for (i = 0; i < n_got ; offset += 4, i++) {

Patch:
patch: @@ -12,6 +12,9 @@ static void *load_bytes(RBinFile *arch, const ut8 *buf, ut64 sz, ut64 loaddr, Sd
 		return NULL;
 	}
 	RBuffer *tbuf = r_buf_new ();
+	if (!tbuf) {
+		return NULL;
+	}
 	r_buf_set_bytes (tbuf, buf, sz);
 	struct r_bin_bflt_obj *res = r_bin_bflt_new_buf (tbuf);
 	r_buf_free (tbuf);
@@ -47,7 +50,8 @@ static void __patch_reloc(RBuffer *buf, ut32 addr_to_patch, ut32 data_offset) {
 	r_buf_write_at (buf, addr_to_patch, (void *)val, sizeof (val));
 }
 
-static int search_old_relocation(struct reloc_struct_t *reloc_table, ut32 addr_to_patch, int n_reloc) {
+static int search_old_relocation (struct reloc_struct_t *reloc_table,
+				  ut32 addr_to_patch, int n_reloc) {
 	int i;
 	for (i = 0; i < n_reloc; i++) {
 		if (addr_to_patch == reloc_table[i].data_offset) {
@@ -163,7 +167,8 @@ static RList *relocs(RBinFile *arch) {
 			if (amount < n_got || amount > UT32_MAX) {
 				goto out_error;
 			}
-			struct reloc_struct_t *got_table = calloc (1, n_got * sizeof (ut32));
+			struct reloc_struct_t *got_table = calloc (
+				1, n_got * sizeof (struct reloc_struct_t));
 			if (got_table) {
 				ut32 offset = 0;
 				for (i = 0; i < n_got ; offset += 4, i++) {
path: libr/bin/p/bin_bflt.c