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>