Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 10 Dec 2014 08:36:08 +0000 (UTC)
From:      Xin LI <delphij@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org
Subject:   svn commit: r275671 - in releng/10.0: . contrib/file sys/conf
Message-ID:  <201412100836.sBA8a8B1038544@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: delphij
Date: Wed Dec 10 08:36:07 2014
New Revision: 275671
URL: https://svnweb.freebsd.org/changeset/base/275671

Log:
  Fix multiple vulnerabilities in file(1) and libmagic(3).
  
  Security:	FreeBSD-SA-14:28.file
  Security:	CVE-2014-3710, CVE-2014-8116, CVE-2014-8117
  Approved by:	so

Modified:
  releng/10.0/UPDATING
  releng/10.0/contrib/file/elfclass.h
  releng/10.0/contrib/file/readelf.c
  releng/10.0/contrib/file/softmagic.c
  releng/10.0/sys/conf/newvers.sh

Modified: releng/10.0/UPDATING
==============================================================================
--- releng/10.0/UPDATING	Wed Dec 10 08:35:55 2014	(r275670)
+++ releng/10.0/UPDATING	Wed Dec 10 08:36:07 2014	(r275671)
@@ -16,6 +16,9 @@ from older versions of FreeBSD, try WITH
 stable/10, and then rebuild without this option. The bootstrap process from
 older version of current is a bit fragile.
 
+20141210:	p13	FreeBSD-SA-14:28.file
+	Fix multiple vulnerabilities in file(1) and libmagic(3).
+
 20141104:	p12	FreeBSD-SA-14:24.sshd
 			FreeBSD-SA-14:25.setlogin
 			FreeBSD-SA-14:26.ftp

Modified: releng/10.0/contrib/file/elfclass.h
==============================================================================
--- releng/10.0/contrib/file/elfclass.h	Wed Dec 10 08:35:55 2014	(r275670)
+++ releng/10.0/contrib/file/elfclass.h	Wed Dec 10 08:36:07 2014	(r275671)
@@ -35,10 +35,12 @@
 	switch (type) {
 #ifdef ELFCORE
 	case ET_CORE:
+		phnum = elf_getu16(swap, elfhdr.e_phnum);
+		if (phnum > MAX_PHNUM)
+			return toomany(ms, "program", phnum);
 		flags |= FLAGS_IS_CORE;
 		if (dophn_core(ms, clazz, swap, fd,
-		    (off_t)elf_getu(swap, elfhdr.e_phoff),
-		    elf_getu16(swap, elfhdr.e_phnum), 
+		    (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
 		    (size_t)elf_getu16(swap, elfhdr.e_phentsize),
 		    fsize, &flags) == -1)
 			return -1;
@@ -46,18 +48,24 @@
 #endif
 	case ET_EXEC:
 	case ET_DYN:
+		phnum = elf_getu16(swap, elfhdr.e_phnum);
+		if (phnum > MAX_PHNUM)
+			return toomany(ms, "program", phnum);
+		shnum = elf_getu16(swap, elfhdr.e_shnum);
+		if (shnum > MAX_SHNUM)
+			return toomany(ms, "section", shnum);
 		if (dophn_exec(ms, clazz, swap, fd,
-		    (off_t)elf_getu(swap, elfhdr.e_phoff),
-		    elf_getu16(swap, elfhdr.e_phnum), 
+		    (off_t)elf_getu(swap, elfhdr.e_phoff), phnum,
 		    (size_t)elf_getu16(swap, elfhdr.e_phentsize),
-		    fsize, &flags, elf_getu16(swap, elfhdr.e_shnum))
-		    == -1)
+		    fsize, &flags, shnum) == -1)
 			return -1;
 		/*FALLTHROUGH*/
 	case ET_REL:
+		shnum = elf_getu16(swap, elfhdr.e_shnum);
+		if (shnum > MAX_SHNUM)
+			return toomany(ms, "section", shnum);
 		if (doshn(ms, clazz, swap, fd,
-		    (off_t)elf_getu(swap, elfhdr.e_shoff),
-		    elf_getu16(swap, elfhdr.e_shnum),
+		    (off_t)elf_getu(swap, elfhdr.e_shoff), shnum,
 		    (size_t)elf_getu16(swap, elfhdr.e_shentsize),
 		    fsize, &flags, elf_getu16(swap, elfhdr.e_machine)) == -1)
 			return -1;

Modified: releng/10.0/contrib/file/readelf.c
==============================================================================
--- releng/10.0/contrib/file/readelf.c	Wed Dec 10 08:35:55 2014	(r275670)
+++ releng/10.0/contrib/file/readelf.c	Wed Dec 10 08:36:07 2014	(r275671)
@@ -60,6 +60,18 @@ private uint16_t getu16(int, uint16_t);
 private uint32_t getu32(int, uint32_t);
 private uint64_t getu64(int, uint64_t);
 
+#define MAX_PHNUM	256
+#define	MAX_SHNUM	1024
+
+private int
+toomany(struct magic_set *ms, const char *name, uint16_t num)
+{
+	if (file_printf(ms, ", too many %s header sections (%u)", name, num
+	    ) == -1)
+		return -1;
+	return 0;
+}
+
 private uint16_t
 getu16(int swap, uint16_t value)
 {
@@ -384,13 +396,13 @@ donote(struct magic_set *ms, void *vbuf,
 	if (namesz & 0x80000000) {
 	    (void)file_printf(ms, ", bad note name size 0x%lx",
 		(unsigned long)namesz);
-	    return offset;
+	    return 0;
 	}
 
 	if (descsz & 0x80000000) {
 	    (void)file_printf(ms, ", bad note description size 0x%lx",
 		(unsigned long)descsz);
-	    return offset;
+	    return 0;
 	}
 
 
@@ -847,6 +859,7 @@ doshn(struct magic_set *ms, int clazz, i
 	Elf32_Shdr sh32;
 	Elf64_Shdr sh64;
 	int stripped = 1;
+	size_t nbadcap = 0;
 	void *nbuf;
 	off_t noff, coff;
 	uint64_t cap_hw1 = 0;	/* SunOS 5.x hardware capabilites */
@@ -919,6 +932,8 @@ doshn(struct magic_set *ms, int clazz, i
 			free(nbuf);
 			break;
 		case SHT_SUNW_cap:
+			if (nbadcap > 5)
+				break;
 			if (lseek(fd, (off_t)xsh_offset, SEEK_SET) ==
 			    (off_t)-1) {
 				file_badseek(ms);
@@ -955,6 +970,8 @@ doshn(struct magic_set *ms, int clazz, i
 					    (unsigned long long)xcap_tag,
 					    (unsigned long long)xcap_val) == -1)
 						return -1;
+					if (nbadcap++ > 2)
+						coff = xsh_size;
 					break;
 				}
 			}
@@ -1142,7 +1159,7 @@ file_tryelf(struct magic_set *ms, int fd
 	int flags = 0;
 	Elf32_Ehdr elf32hdr;
 	Elf64_Ehdr elf64hdr;
-	uint16_t type;
+	uint16_t type, phnum, shnum;
 
 	if (ms->flags & (MAGIC_MIME|MAGIC_APPLE))
 		return 0;

Modified: releng/10.0/contrib/file/softmagic.c
==============================================================================
--- releng/10.0/contrib/file/softmagic.c	Wed Dec 10 08:35:55 2014	(r275670)
+++ releng/10.0/contrib/file/softmagic.c	Wed Dec 10 08:36:07 2014	(r275671)
@@ -61,6 +61,9 @@ private void cvt_32(union VALUETYPE *, c
 private void cvt_64(union VALUETYPE *, const struct magic *);
 
 #define OFFSET_OOB(n, o, i)	((n) < (o) || (i) > ((n) - (o)))
+
+#define MAX_RECURSION_LEVEL	10
+
 /*
  * softmagic - lookup one file in parsed, in-memory copy of database
  * Passed the name and FILE * of one file to be typed.
@@ -1027,7 +1030,7 @@ mget(struct magic_set *ms, const unsigne
 	uint32_t count = m->str_range;
 	union VALUETYPE *p = &ms->ms_value;
 
-        if (recursion_level >= 20) {
+        if (recursion_level >= MAX_RECURSION_LEVEL) {
                 file_error(ms, 0, "recursion nesting exceeded");
                 return -1;
         }

Modified: releng/10.0/sys/conf/newvers.sh
==============================================================================
--- releng/10.0/sys/conf/newvers.sh	Wed Dec 10 08:35:55 2014	(r275670)
+++ releng/10.0/sys/conf/newvers.sh	Wed Dec 10 08:36:07 2014	(r275671)
@@ -32,7 +32,7 @@
 
 TYPE="FreeBSD"
 REVISION="10.0"
-BRANCH="RELEASE-p12"
+BRANCH="RELEASE-p13"
 if [ "X${BRANCH_OVERRIDE}" != "X" ]; then
 	BRANCH=${BRANCH_OVERRIDE}
 fi



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201412100836.sBA8a8B1038544>