[Midnightbsd-cvs] src [6955] trunk: Fix a DOS attack on libmagic
laffer1 at midnightbsd.org
laffer1 at midnightbsd.org
Thu Dec 11 08:04:28 EST 2014
Revision: 6955
http://svnweb.midnightbsd.org/src/?rev=6955
Author: laffer1
Date: 2014-12-11 08:04:28 -0500 (Thu, 11 Dec 2014)
Log Message:
-----------
Fix a DOS attack on libmagic
Modified Paths:
--------------
trunk/UPDATING
trunk/contrib/file/elfclass.h
trunk/contrib/file/readelf.c
trunk/contrib/file/softmagic.c
Modified: trunk/UPDATING
===================================================================
--- trunk/UPDATING 2014-11-27 15:08:44 UTC (rev 6954)
+++ trunk/UPDATING 2014-12-11 13:04:28 UTC (rev 6955)
@@ -1,5 +1,10 @@
Updating Information for MidnightBSD users.
+20141211:
+ Fix a security issue with file and libmagic that can allow
+ an attacker to create a denial of service attack on any
+ program that uses libmagic.
+
20141117:
Add support for UDP Lite protocol aka RFC 3828 to IPv4 and IPv6
stacks.
Modified: trunk/contrib/file/elfclass.h
===================================================================
--- trunk/contrib/file/elfclass.h 2014-11-27 15:08:44 UTC (rev 6954)
+++ trunk/contrib/file/elfclass.h 2014-12-11 13:04:28 UTC (rev 6955)
@@ -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),
(int)elf_getu16(swap, elfhdr.e_shstrndx)) == -1)
Modified: trunk/contrib/file/readelf.c
===================================================================
--- trunk/contrib/file/readelf.c 2014-11-27 15:08:44 UTC (rev 6954)
+++ trunk/contrib/file/readelf.c 2014-12-11 13:04:28 UTC (rev 6955)
@@ -60,6 +60,18 @@
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)
{
@@ -492,13 +504,13 @@
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;
}
@@ -900,6 +912,7 @@
Elf32_Shdr sh32;
Elf64_Shdr sh64;
int stripped = 1;
+ size_t nbadcap = 0;
void *nbuf;
off_t noff, coff, name_off;
uint64_t cap_hw1 = 0; /* SunOS 5.x hardware capabilites */
@@ -977,6 +990,8 @@
free(nbuf);
break;
case SHT_SUNW_cap:
+ if (nbadcap > 5)
+ break;
switch (mach) {
case EM_SPARC:
case EM_SPARCV9:
@@ -1053,6 +1068,8 @@
(unsigned long long)xcap_tag,
(unsigned long long)xcap_val) == -1)
return -1;
+ if (nbadcap++ > 2)
+ coff = xsh_size;
break;
}
}
@@ -1233,7 +1250,7 @@
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: trunk/contrib/file/softmagic.c
===================================================================
--- trunk/contrib/file/softmagic.c 2014-11-27 15:08:44 UTC (rev 6954)
+++ trunk/contrib/file/softmagic.c 2014-12-11 13:04:28 UTC (rev 6955)
@@ -67,6 +67,9 @@
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.
@@ -1200,7 +1203,7 @@
union VALUETYPE *p = &ms->ms_value;
struct mlist ml;
- if (recursion_level >= 20) {
+ if (recursion_level >= MAX_RECURSION_LEVEL) {
file_error(ms, 0, "recursion nesting exceeded");
return -1;
}
More information about the Midnightbsd-cvs
mailing list