CVE-2017-16359 (published 2017-11-01T17:29Z)

In radare 2.0.1, a pointer wraparound vulnerability exists in store_versioninfo_gnu_verdef() in libr/bin/format/elf/elf.c.

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: Khairul Kasmiran
author_date: 2017-11-01 20:44:46+08:00
msg: Fix #8764 a 3rd time since 2nd time is UB and can be optimized away
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: elf.c
change_type: ModificationType.MODIFY
diff: @@ -734,6 +734,7 @@ static Sdb *store_versioninfo_gnu_verdef(ELFOBJ *bin, Elf_(Shdr) *shdr, int sz)
 	for (cnt = 0, i = 0; i >= 0 && cnt < shdr->sh_info && ((char *)defs + i < end); ++cnt) {
 		Sdb *sdb_verdef = sdb_new0 ();
 		char *vstart = ((char*)defs) + i;
+		size_t vstart_off = i;
 		char key[32] = {0};
 		Elf_(Verdef) *verdef = (Elf_(Verdef)*)vstart;
 		Elf_(Verdaux) aux = {0};
@@ -749,11 +750,12 @@ static Sdb *store_versioninfo_gnu_verdef(ELFOBJ *bin, Elf_(Shdr) *shdr, int sz)
 		verdef->vd_aux = READ32 (dfs, j)
 		verdef->vd_next = READ32 (dfs, j)
 		int vdaux = verdef->vd_aux;
-		if (vdaux < 1 || vstart + vdaux < vstart) {
+		if (vdaux < 1 || shdr->sh_size - vstart_off < vdaux) {
 			sdb_free (sdb_verdef);
 			goto out_error;
 		}
 		vstart += vdaux;
+		vstart_off += vdaux;
 		if (vstart > end || vstart + sizeof (Elf_(Verdaux)) > end) {
 			sdb_free (sdb_verdef);
 			goto out_error;
@@ -781,6 +783,7 @@ static Sdb *store_versioninfo_gnu_verdef(ELFOBJ *bin, Elf_(Shdr) *shdr, int sz)
 			Sdb *sdb_parent = sdb_new0 ();
 			isum += aux.vda_next;
 			vstart += aux.vda_next;
+			vstart_off += aux.vda_next;
 			if (vstart > end || vstart + sizeof (Elf_(Verdaux)) > end) {
 				sdb_free (sdb_verdef);
 				sdb_free (sdb_parent);

programming_language: C
repo_url: https://github.com/radare/radare2
commit_details: repo_url: https://github.com/radare/radare2
author: Khairul Kasmiran
author_date: 2017-11-01 01:52:54+08:00
msg: Fix #8764 differently since ptr diff might not fit in ptrdiff_t
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: elf.c
change_type: ModificationType.MODIFY
diff: @@ -749,7 +749,7 @@ static Sdb *store_versioninfo_gnu_verdef(ELFOBJ *bin, Elf_(Shdr) *shdr, int sz)
 		verdef->vd_aux = READ32 (dfs, j)
 		verdef->vd_next = READ32 (dfs, j)
 		int vdaux = verdef->vd_aux;
-		if (vdaux < 1 || (char *)UINTPTR_MAX - vstart < vdaux) {
+		if (vdaux < 1 || vstart + vdaux < vstart) {
 			sdb_free (sdb_verdef);
 			goto out_error;
 		}

programming_language: C
repo_url: https://github.com/radare/radare2
commit_details: repo_url: https://github.com/radare/radare2
author: Khairul Kasmiran
author_date: 2017-10-31 23:35:41+08:00
msg: Fix #8764 - huge vd_aux caused pointer wraparound
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: elf.c
change_type: ModificationType.MODIFY
diff: @@ -731,7 +731,7 @@ static Sdb *store_versioninfo_gnu_verdef(ELFOBJ *bin, Elf_(Shdr) *shdr, int sz)
 	sdb_num_set (sdb, "link", shdr->sh_link, 0);
 	sdb_set (sdb, "link_section_name", link_section_name, 0);
 
-	for (cnt = 0, i = 0; i >= 0 && cnt < shdr->sh_info && ((char *)defs + i < end); ++cnt) {
+	for (cnt = 0, i = 0; i >= 0 && cnt < shdr->sh_info && (end - (char *)defs > i); ++cnt) {
 		Sdb *sdb_verdef = sdb_new0 ();
 		char *vstart = ((char*)defs) + i;
 		char key[32] = {0};
@@ -749,12 +749,12 @@ static Sdb *store_versioninfo_gnu_verdef(ELFOBJ *bin, Elf_(Shdr) *shdr, int sz)
 		verdef->vd_aux = READ32 (dfs, j)
 		verdef->vd_next = READ32 (dfs, j)
 		int vdaux = verdef->vd_aux;
-		if (vdaux < 1) {
+		if (vdaux < 1 || (char *)UINTPTR_MAX - vstart < vdaux) {
 			sdb_free (sdb_verdef);
 			goto out_error;
 		}
 		vstart += vdaux;
-		if (vstart > end || vstart + sizeof (Elf_(Verdaux)) > end) {
+		if (vstart > end || end - vstart < sizeof (Elf_(Verdaux))) {
 			sdb_free (sdb_verdef);
 			goto out_error;
 		}
@@ -781,7 +781,7 @@ static Sdb *store_versioninfo_gnu_verdef(ELFOBJ *bin, Elf_(Shdr) *shdr, int sz)
 			Sdb *sdb_parent = sdb_new0 ();
 			isum += aux.vda_next;
 			vstart += aux.vda_next;
-			if (vstart > end || vstart + sizeof(Elf_(Verdaux)) > end) {
+			if (vstart > end || end - vstart < sizeof (Elf_(Verdaux))) {
 				sdb_free (sdb_verdef);
 				sdb_free (sdb_parent);
 				goto out_error;

programming_language: C