Browse Source

Fix several security issues, Closes: #773148

- CVE-2014-8116
  The ELF parser (readelf.c) in file before 5.21 allows remote attackers ...
- CVE-2014-8117
  softmagic.c in file before 5.21 does not properly limit recursion
- TEMP-0000000-C482B4
  out-of-bounds memory access

Cherry-picks upstream commits:

- FILE5_11-8-g0de3251   (prerequisite for CVE-2014-8117)
- FILE5_17-8-gc0c0032   (prerequisite for CVE-2014-8117)
- FILE5_20-21-g59e6383  (TEMP-0000000-C482B4)
- FILE5_20-27-gb4c0114  (CVE-2014-8116)
- FILE5_20-28-gd7cdad0  (CVE-2014-8116)
- FILE5_20-29-g6f737dd  (CVE-2014-8117)
- FILE5_20-34-g90018fe  (regression in fix for CVE-2014-8117)
- FILE5_20-35-g5063ca3  (amendment for CVE-2014-8117)
- FILE5_20-42-g6bf4527  (CVE-2014-8117)
Christoph Biedl 10 years ago
parent
commit
2dbe08d16b

+ 104 - 0
debian/patches/CVE-2014-8116.1.b4c0114.patch

@@ -0,0 +1,104 @@
+Subject: Limit the number of program and section header number of sections to be (...)
+ID: CVE-2014-8116
+Upstream-Author: Christos Zoulas <christos@zoulas.com>
+Date: Sat Nov 22 16:04:29 2014 +0000
+Origin: FILE5_20-27-gb4c0114
+Last-Update: 2015-01-09
+
+    - limit the number of program and section header number of sections to be
+      processed to avoid excessive processing time.
+    - if a bad note is found, return 0 to stop processing immediately.
+
+--- a/src/elfclass.h
++++ b/src/elfclass.h
+@@ -35,9 +35,11 @@
+ 	switch (type) {
+ #ifdef ELFCORE
+ 	case ET_CORE:
++		phnum = elf_getu16(swap, elfhdr.e_phnum);
++		if (phnum > MAX_PHNUM)
++			return toomany(ms, "program", phnum);
+ 		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;
+@@ -45,18 +47,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),
+ 		    &flags,
+ 		    elf_getu16(swap, elfhdr.e_machine)) == -1)
+--- a/src/readelf.c
++++ b/src/readelf.c
+@@ -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)
+ {
+@@ -398,13 +410,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;
+ 	}
+ 
+ 
+@@ -1165,7 +1177,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;

+ 35 - 0
debian/patches/CVE-2014-8116.2.d7cdad0.patch

@@ -0,0 +1,35 @@
+Subject: Stop reporting bad capabilities after the first few
+ID: CVE-2014-8116
+Upstream-Author: Christos Zoulas <christos@zoulas.com>
+Date: Sat Nov 22 23:57:44 2014 +0000
+Origin: FILE5_20-28-gd7cdad0
+Last-Update: 2015-01-09
+
+--- a/src/readelf.c
++++ b/src/readelf.c
+@@ -859,6 +859,7 @@
+ 	Elf32_Shdr sh32;
+ 	Elf64_Shdr sh64;
+ 	int stripped = 1;
++	size_t nbadcap = 0;
+ 	void *nbuf;
+ 	off_t noff;
+ 	uint64_t cap_hw1 = 0;	/* SunOS 5.x hardware capabilites */
+@@ -936,6 +937,8 @@
+ 				file_badread(ms);
+ 				return -1;
+ 			}
++			if (nbadcap > 5)
++				break;
+ 			if (lseek(fd, (off_t)xsh_offset, SEEK_SET) ==
+ 			    (off_t)-1) {
+ 				file_badread(ms);
+@@ -971,6 +974,8 @@
+ 					    (unsigned long long)xcap_tag,
+ 					    (unsigned long long)xcap_val) == -1)
+ 						return -1;
++					if (nbadcap++ > 2)
++						coff = xsh_size;
+ 					break;
+ 				}
+ 			}

+ 54 - 0
debian/patches/CVE-2014-8117.1.0de3251.patch

@@ -0,0 +1,54 @@
+Subject: Only print the description for indirect offsets if a match was found, and add the offset as the number to print
+Upstream-Author: Christos Zoulas <christos@zoulas.com>
+Date: Fri Apr 6 21:15:54 2012 +0000
+Origin: FILE5_11-8-g0de3251
+Last-Update: 2015-01-09
+
+    - only print the description for indirect offsets if a match was found,
+    and add the offset as the number to print.
+
+(prequisite for CVE-2014-8117)
+
+--- a/src/softmagic.c
++++ b/src/softmagic.c
+@@ -1046,6 +1046,8 @@
+     struct magic *m, size_t nbytes, unsigned int cont_level, int recursion_level)
+ {
+ 	uint32_t offset = ms->offset;
++	int rv;
++	char *sbuf, *rbuf;
+ 	union VALUETYPE *p = &ms->ms_value;
+ 
+         if (recursion_level >= 20) {
+@@ -1609,13 +1611,26 @@
+ 	case FILE_INDIRECT:
+ 		if (offset == 0)
+ 			return 0;
+-	  	if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
+-		    file_printf(ms, "%s", m->desc) == -1)
+-			return -1;
+-		if (OFFSET_OOB(nbytes, offset, 0))
++		if (nbytes < offset)
+ 			return 0;
+-		return file_softmagic(ms, s + offset, nbytes - offset,
++		sbuf = ms->o.buf;
++		ms->o.buf = NULL;
++		rv = file_softmagic(ms, s + offset, nbytes - offset,
+ 		    recursion_level, BINTEST);
++		if ((ms->flags & MAGIC_DEBUG) != 0)
++			fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
++		if (rv == 1) {
++			rbuf = ms->o.buf;
++			ms->o.buf = sbuf;
++			if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
++			    file_printf(ms, m->desc, offset) == -1)
++				return -1;
++			if (file_printf(ms, "%s", rbuf) == -1)
++				return -1;
++			free(rbuf);
++		} else
++			ms->o.buf = sbuf;
++		return rv;
+ 
+ 	case FILE_DEFAULT:	/* nothing to check */
+ 	default:

+ 27 - 0
debian/patches/CVE-2014-8117.2.c0c0032.patch

@@ -0,0 +1,27 @@
+Subject: Fix memory leak (Anatol Belski)
+Upstream-Author: Christos Zoulas <christos@zoulas.com>
+Date: Fri Feb 21 14:32:48 2014 +0000
+Origin: FILE5_17-8-gc0c0032
+Last-Update: 2015-01-09
+
+(prequisite for CVE-2014-8117)
+
+--- a/src/softmagic.c
++++ b/src/softmagic.c
+@@ -1623,10 +1623,14 @@
+ 			rbuf = ms->o.buf;
+ 			ms->o.buf = sbuf;
+ 			if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
+-			    file_printf(ms, m->desc, offset) == -1)
++			    file_printf(ms, m->desc, offset) == -1) {
++				free(rbuf);
+ 				return -1;
+-			if (file_printf(ms, "%s", rbuf) == -1)
++			}
++			if (file_printf(ms, "%s", rbuf) == -1) {
++				free(rbuf);
+ 				return -1;
++			}
+ 			free(rbuf);
+ 		} else
+ 			ms->o.buf = sbuf;

+ 141 - 0
debian/patches/CVE-2014-8117.3.6f737dd.patch

@@ -0,0 +1,141 @@
+Subject: Reduce recursion level from 20 to 10 and make a symbolic constant for it. (...)
+ID: CVE-2014-8117
+Upstream-Author: Christos Zoulas <christos@zoulas.com>
+Date: Sun Nov 23 13:54:27 2014 +0000
+Origin: FILE5_20-29-g6f737dd
+Last-Update: 2015-01-09
+
+    - reduce recursion level from 20 to 10 and make a symbolic constant for it.
+    - pull out the guts of saving and restoring the output buffer into functions
+      and take care not to overwrite the error message if an error happened.
+
+--- a/src/file.h
++++ b/src/file.h
+@@ -422,6 +422,14 @@
+ #endif /* __EMX__ */
+ 
+ 
++typedef struct {
++	char *buf;
++	uint32_t offset;
++} file_pushbuf_t;
++
++protected file_pushbuf_t *file_push_buffer(struct magic_set *);
++protected char  *file_pop_buffer(struct magic_set *, file_pushbuf_t *);
++
+ #ifndef COMPILE_ONLY
+ extern const char *file_names[];
+ extern const size_t file_nnames;
+--- a/src/funcs.c
++++ b/src/funcs.c
+@@ -424,3 +424,43 @@
+ #endif /* ENABLE_CONDITIONALS */
+ 	return 0;
+ }
++
++protected file_pushbuf_t *
++file_push_buffer(struct magic_set *ms)
++{
++	file_pushbuf_t *pb;
++
++	if (ms->event_flags & EVENT_HAD_ERR)
++		return NULL;
++
++	if ((pb = (CAST(file_pushbuf_t *, malloc(sizeof(*pb))))) == NULL)
++		return NULL;
++
++	pb->buf = ms->o.buf;
++	pb->offset = ms->offset;
++
++	ms->o.buf = NULL;
++	ms->offset = 0;
++
++	return pb;
++}
++
++protected char *
++file_pop_buffer(struct magic_set *ms, file_pushbuf_t *pb)
++{
++	char *rbuf;
++
++	if (ms->event_flags & EVENT_HAD_ERR) {
++		free(pb->buf);
++		free(pb);
++		return NULL;
++	}
++
++	rbuf = ms->o.buf;
++
++	ms->o.buf = pb->buf;
++	ms->offset = pb->offset;
++
++	free(pb);
++	return rbuf;
++}
+--- a/src/softmagic.c
++++ b/src/softmagic.c
+@@ -61,6 +61,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.
+@@ -1049,11 +1052,12 @@
+     struct magic *m, size_t nbytes, unsigned int cont_level, int recursion_level)
+ {
+ 	uint32_t offset = ms->offset;
++	file_pushbuf_t *pb;
+ 	int rv;
+-	char *sbuf, *rbuf;
++	char *rbuf;
+ 	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;
+         }
+@@ -1614,17 +1618,23 @@
+ 	case FILE_INDIRECT:
+ 		if (offset == 0)
+ 			return 0;
++
+ 		if (nbytes < offset)
+ 			return 0;
+-		sbuf = ms->o.buf;
+-		ms->o.buf = NULL;
++
++		if ((pb = file_push_buffer(ms)) == NULL)
++			return -1;
++
+ 		rv = file_softmagic(ms, s + offset, nbytes - offset,
+ 		    recursion_level, BINTEST);
+ 		if ((ms->flags & MAGIC_DEBUG) != 0)
+ 			fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
++
++		rbuf = file_pop_buffer(ms, pb);
++		if (rbuf == NULL)
++			return -1;
++
+ 		if (rv == 1) {
+-			rbuf = ms->o.buf;
+-			ms->o.buf = sbuf;
+ 			if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
+ 			    file_printf(ms, m->desc, offset) == -1) {
+ 				free(rbuf);
+@@ -1634,9 +1644,8 @@
+ 				free(rbuf);
+ 				return -1;
+ 			}
+-			free(rbuf);
+-		} else
+-			ms->o.buf = sbuf;
++		}
++		free(rbuf);
+ 		return rv;
+ 
+ 	case FILE_DEFAULT:	/* nothing to check */

+ 175 - 0
debian/patches/CVE-2014-8117.4.90018fe.patch

@@ -0,0 +1,175 @@
+Subject: Bump recursion to 15, and allow it to be set from the command line
+Upstream-Author: Christos Zoulas <christos@zoulas.com>
+Date: Thu Nov 27 15:40:36 2014 +0000
+Origin: FILE5_20-34-g90018fe
+Last-Update: 2015-01-09
+
+--- a/src/file.c
++++ b/src/file.c
+@@ -106,7 +106,7 @@
+ #undef OPT_LONGONLY
+     {0, 0, NULL, 0}
+ };
+-#define OPTSTRING	"bcCde:f:F:hikLm:nNprsvz0"
++#define OPTSTRING	"bcCde:f:F:hikLm:nNprR:svz0"
+ 
+ private const struct {
+ 	const char *name;
+@@ -144,6 +144,7 @@
+ 	size_t i;
+ 	int action = 0, didsomefiles = 0, errflg = 0;
+ 	int flags = 0, e = 0;
++	size_t max_recursion = 0;
+ 	struct magic_set *magic = NULL;
+ 	int longindex;
+ 	const char *magicfile = NULL;		/* where the magic is	*/
+@@ -244,6 +245,9 @@
+ 		case 'r':
+ 			flags |= MAGIC_RAW;
+ 			break;
++		case 'R':
++			max_recursion = atoi(optarg);
++			break;
+ 		case 's':
+ 			flags |= MAGIC_DEVICES;
+ 			break;
+@@ -303,6 +307,15 @@
+ 		if (magic == NULL)
+ 			if ((magic = load(magicfile, flags)) == NULL)
+ 				return 1;
++		if (max_recursion) {
++			if (magic_setparam(magic, MAGIC_PARAM_MAX_RECURSION,
++			    &max_recursion) == -1) {
++				(void)fprintf(stderr,
++				    "%s: Can't set recurision %s\n", progname,
++				    strerror(errno));
++				return 1;
++			}
++		}
+ 		break;
+ 	}
+ 
+--- a/src/file.h
++++ b/src/file.h
+@@ -363,6 +363,8 @@
+ 	/* FIXME: Make the string dynamically allocated so that e.g.
+ 	   strings matched in files can be longer than MAXstring */
+ 	union VALUETYPE ms_value;	/* either number or string */
++	size_t max_recursion;
++#define	FILE_MAX_RECURSION	15
+ };
+ 
+ /* Type for Unicode characters */
+--- a/src/file_opts.h
++++ b/src/file_opts.h
+@@ -43,6 +43,7 @@
+ OPT('p', "preserve-date", 0, "        preserve access times on files\n")
+ #endif
+ OPT('r', "raw", 0, "                  don't translate unprintable chars to \\ooo\n")
++OPT('R', "recursion", 0, "            set maximum recursion level\n")
+ OPT('s', "special-files", 0, "        treat special (block/char devices) files as\n"
+     "                             ordinary ones\n")
+ OPT('C', "compile", 0, "              compile file specified by -m\n")
+--- a/src/magic.c
++++ b/src/magic.c
+@@ -142,6 +142,7 @@
+ 	ms->mlist = NULL;
+ 	ms->file = "unknown";
+ 	ms->line = 0;
++	ms->max_recursion = FILE_MAX_RECURSION;
+ 	return ms;
+ free:
+ 	free(ms);
+@@ -410,3 +411,29 @@
+ 	ms->flags = flags;
+ 	return 0;
+ }
++
++public int
++magic_setparam(struct magic_set *ms, int param, const void *val)
++{
++	switch (param) {
++	case MAGIC_PARAM_MAX_RECURSION:
++		ms->max_recursion = *(const size_t *)val;
++		return 0;
++	default:
++		errno = EINVAL;
++		return -1;
++	}
++}
++
++public int
++magic_getparam(struct magic_set *ms, int param, void *val)
++{
++	switch (param) {
++	case MAGIC_PARAM_MAX_RECURSION:
++		*(size_t *)val = ms->max_recursion;
++		return 0;
++	default:
++		errno = EINVAL;
++		return -1;
++	}
++}
+--- a/src/magic.h
++++ b/src/magic.h
+@@ -82,6 +82,10 @@
+ int magic_check(magic_t, const char *);
+ int magic_errno(magic_t);
+ 
++#define MAGIC_PARAM_MAX_RECURSION	0
++int magic_setparam(magic_t, int, const void *);
++int magic_getparam(magic_t, int, void *);
++
+ #ifdef __cplusplus
+ };
+ #endif
+--- a/src/softmagic.c
++++ b/src/softmagic.c
+@@ -43,9 +43,9 @@
+ 
+ 
+ private int match(struct magic_set *, struct magic *, uint32_t,
+-    const unsigned char *, size_t, int, int);
++    const unsigned char *, size_t, int, size_t);
+ private int mget(struct magic_set *, const unsigned char *,
+-    struct magic *, size_t, unsigned int, int);
++    struct magic *, size_t, unsigned int, size_t);
+ private int magiccheck(struct magic_set *, struct magic *);
+ private int32_t mprint(struct magic_set *, struct magic *);
+ private int32_t moffset(struct magic_set *, struct magic *);
+@@ -62,8 +62,6 @@
+ 
+ #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.
+@@ -110,7 +108,7 @@
+  */
+ private int
+ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic,
+-    const unsigned char *s, size_t nbytes, int mode, int recursion_level)
++    const unsigned char *s, size_t nbytes, int mode, size_t recursion_level)
+ {
+ 	uint32_t magindex = 0;
+ 	unsigned int cont_level = 0;
+@@ -1049,7 +1047,7 @@
+ 
+ private int
+ mget(struct magic_set *ms, const unsigned char *s,
+-    struct magic *m, size_t nbytes, unsigned int cont_level, int recursion_level)
++    struct magic *m, size_t nbytes, unsigned int cont_level, size_t recursion_level)
+ {
+ 	uint32_t offset = ms->offset;
+ 	file_pushbuf_t *pb;
+@@ -1057,7 +1055,7 @@
+ 	char *rbuf;
+ 	union VALUETYPE *p = &ms->ms_value;
+ 
+-	if (recursion_level >= MAX_RECURSION_LEVEL) {
++	if (recursion_level >= ms->max_recursion) {
+                 file_error(ms, 0, "recursion nesting exceeded");
+                 return -1;
+         }

+ 72 - 0
debian/patches/CVE-2014-8117.5.5063ca3.patch

@@ -0,0 +1,72 @@
+Subject: Document changes
+Upstream-Author: Christos Zoulas <christos@zoulas.com>
+Date: Thu Nov 27 16:15:06 2014 +0000
+Origin: FILE5_20-35-g5063ca3
+Last-Update: 2015-01-09
+
+--- a/doc/file.man
++++ b/doc/file.man
+@@ -16,6 +16,7 @@
+ .Op Fl F Ar separator
+ .Op Fl f Ar namefile
+ .Op Fl m Ar magicfiles
++.Op Fl R Ar maxrecursion
+ .Ar
+ .Ek -words
+ .Nm
+@@ -278,6 +279,11 @@
+ Normally
+ .Nm
+ translates unprintable characters to their octal representation.
++.It Fl R , Fl Fl recursion Ar maxlevel
++Set the maximum recursion level for indirect type magic or name/use entry
++invocations.
++The default is
++.Dv 15 .
+ .It Fl s , -special-files
+ Normally,
+ .Nm
+--- a/doc/libmagic.man
++++ b/doc/libmagic.man
+@@ -38,6 +38,8 @@
+ .Nm magic_check ,
+ .Nm magic_compile ,
+ .Nm magic_load
++.Nm magic_setparam ,
++.Nm magic_getparam ,
+ .Nd Magic number recognition library.
+ .Sh LIBRARY
+ .Lb libmagic
+@@ -62,7 +64,9 @@
+ .Ft int
+ .Fn magic_compile "magic_t cookie, const char *filename"
+ .Ft int
+-.Fn magic_load "magic_t cookie, const char *filename"
++.Fn magic_getparam "magic_t cookie" "int param" "void *value"
++.Ft int
++.Fn magic_setparam "magic_t cookie" "int param" "const void *value"
+ .Sh DESCRIPTION
+ These functions
+ operate on the magic database file
+@@ -204,6 +208,21 @@
+ adds
+ .Dq .mgc
+ to the database filename as appropriate.
++.Pp
++The
++.Fn magic_getparam
++and
++.Fn magic_setparam
++allow getting and setting various limits related to the the magic
++library.
++.Bl -column "MAGIC_PARAM_MAX_RECURSION" "size_t" "Default" -offset indent
++.It Sy "Parameter" Ta Sy "Type" Ta Sy "Default
++.It Li MAGIC_PARAM_MAX_RECURSION Ta size_t Ta 15
++.El
++The
++.Dv MAGIC_PARAM_MAX_RECURSION
++parameter controls how many levels of recursion will be followed for
++indirect magic entries or for name/use calls.
+ .Sh RETURN VALUES
+ The function
+ .Fn magic_open

+ 18 - 0
debian/patches/CVE-2014-8117.6.6bf4527.patch

@@ -0,0 +1,18 @@
+Subject: Don't bail if there was no error, buf could have been NULL on entry
+ID: CVE-2014-8117
+Upstream-Author: Christos Zoulas <christos@zoulas.com>
+Date: Thu Dec 4 15:22:05 2014 +0000
+Origin: FILE5_20-42-g6bf4527
+Last-Update: 2015-01-09
+
+--- a/src/softmagic.c
++++ b/src/softmagic.c
+@@ -1629,7 +1629,7 @@
+ 			fprintf(stderr, "indirect @offs=%u[%d]\n", offset, rv);
+ 
+ 		rbuf = file_pop_buffer(ms, pb);
+-		if (rbuf == NULL)
++		if (rbuf == NULL && ms->event_flags & EVENT_HAD_ERR)
+ 			return -1;
+ 
+ 		if (rv == 1) {

+ 32 - 0
debian/patches/TEMP-0000000-C482B4.59e6383.patch

@@ -0,0 +1,32 @@
+Subject: PR/398: Correctly truncate pascal strings (fixes out of bounds read of 1, 2, or 4 bytes)
+ID: TEMP-0000000-C482B4
+Upstream-Author: Christos Zoulas <christos@zoulas.com>
+Date: Tue Nov 11 17:48:23 2014 +0000
+Origin: FILE5_20-21-g59e6383
+Last-Update: 2015-01-09
+
+    PR/398: Correctly truncate pascal strings (fixes out of bounds read of 1, 2,
+    or 4 bytes).
+
+--- a/src/softmagic.c
++++ b/src/softmagic.c
+@@ -803,14 +803,17 @@
+ 		size_t sz = file_pstring_length_size(m);
+ 		char *ptr1 = p->s, *ptr2 = ptr1 + sz;
+ 		size_t len = file_pstring_get_length(m, ptr1);
+-		if (len >= sizeof(p->s)) {
++		sz = sizeof(p->s) - sz; /* maximum length of string */
++		if (len >= sz) {
+ 			/*
+ 			 * The size of the pascal string length (sz)
+ 			 * is 1, 2, or 4. We need at least 1 byte for NUL
+ 			 * termination, but we've already truncated the
+ 			 * string by p->s, so we need to deduct sz.
++			 * Because we can use one of the bytes of the length
++			 * after we shifted as NUL termination.
+ 			 */ 
+-			len = sizeof(p->s) - sz;
++			len = sz;
+ 		}
+ 		while (len--)
+ 			*ptr1++ = *ptr2++;

+ 10 - 0
debian/patches/series

@@ -99,3 +99,13 @@ CVE-2014-3487.patch
 CVE-2014-3538.patch
 CVE-2014-3587.patch
 CVE-2014-3710.patch
+
+CVE-2014-8117.1.0de3251.patch
+CVE-2014-8117.2.c0c0032.patch
+TEMP-0000000-C482B4.59e6383.patch
+CVE-2014-8116.1.b4c0114.patch
+CVE-2014-8116.2.d7cdad0.patch
+CVE-2014-8117.3.6f737dd.patch
+CVE-2014-8117.4.90018fe.patch
+CVE-2014-8117.5.5063ca3.patch
+CVE-2014-8117.6.6bf4527.patch