pkgsrc-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

patch: fix CVE-2019-8906, CVE-2019-8904 (not sure about CVE-2019-8905, CVE-2019-8907) in sysutils/file



Hi,

I cherry-picked some patches for the recent vulnerabilities in
sysutils/file from the git repo at https://github.com/file/file/

They needed minor modifications for pkgsrc as we are lagging some
versions behind (pkgsrc: file-5.32; latest on astron: file-5.36).

In the bugtracker for file I can see only 2 CVEs mentioned out of 4, but
there are comments by Christos Zoulas referring to some of the
bugtracker entries as being the same (or being fixed by the same patch).

I tested against the PoC files from the bugtracker, and file does not
crash anymore after these patches. Hopefully they are complete, but I
cannot be really sure.

Regards
Matthias
$NetBSD$

Avoid OOB read (found by ASAN reported by F. Alonso) (CVE-2019-8906)

https://github.com/file/file/commit/2858eaf99f6cc5aae129bcbf1e24ad160240185f

--- src/readelf.c.orig	2019-02-19 11:19:25.000000000 +0000
+++ src/readelf.c
@@ -720,7 +720,7 @@ do_core_note(struct magic_set *ms, unsig
 			char sbuf[512];
 			struct NetBSD_elfcore_procinfo pi;
 			memset(&pi, 0, sizeof(pi));
-			memcpy(&pi, nbuf + doff, descsz);
+			memcpy(&pi, nbuf + doff, MIN(descsz, sizeof(pi)));
 
 			if (file_printf(ms, ", from '%.31s', pid=%u, uid=%u, "
 			    "gid=%u, nlwps=%u, lwp=%u (signal %u/code %u)",
$NetBSD$

fix PR/62: spinpx: limit size of file_printable.  (CVE-2019-8904)

https://bugs.astron.com/view.php?id=62
https://github.com/file/file/commit/d65781527c8134a1202b2649695d48d5701ac60b

--- src/file.h.orig	2017-08-28 13:39:18.000000000 +0000
+++ src/file.h
@@ -491,7 +491,7 @@ protected int file_looks_utf8(const unsi
     size_t *);
 protected size_t file_pstring_length_size(const struct magic *);
 protected size_t file_pstring_get_length(const struct magic *, const char *);
-protected char * file_printable(char *, size_t, const char *);
+protected char * file_printable(char *, size_t, const char *, size_t);
 #ifdef __EMX__
 protected int file_os2_apptype(struct magic_set *, const char *, const void *,
     size_t);
$NetBSD$

fix PR/62: spinpx: limit size of file_printable.  (CVE-2019-8904)

https://bugs.astron.com/view.php?id=62
https://github.com/file/file/commit/d65781527c8134a1202b2649695d48d5701ac60b

--- src/funcs.c.orig	2017-08-28 13:39:18.000000000 +0000
+++ src/funcs.c
@@ -581,12 +581,13 @@ file_pop_buffer(struct magic_set *ms, fi
  * convert string to ascii printable format.
  */
 protected char *
-file_printable(char *buf, size_t bufsiz, const char *str)
+file_printable(char *buf, size_t bufsiz, const char *str, size_t slen)
 {
-	char *ptr, *eptr;
+	char *ptr, *eptr = buf + bufsiz - 1;
 	const unsigned char *s = (const unsigned char *)str;
+	const unsigned char *es = s + slen;
 
-	for (ptr = buf, eptr = ptr + bufsiz - 1; ptr < eptr && *s; s++) {
+	for (ptr = buf;  ptr < eptr && s < es && *s; s++) {
 		if (isprint(*s)) {
 			*ptr++ = *s;
 			continue;
$NetBSD$

fix PR/62: spinpx: limit size of file_printable.  (CVE-2019-8904)

https://bugs.astron.com/view.php?id=62
https://github.com/file/file/commit/d65781527c8134a1202b2649695d48d5701ac60b

--- src/readelf.c.orig	2019-02-19 10:57:44.000000000 +0000
+++ src/readelf.c
@@ -725,7 +725,7 @@ do_core_note(struct magic_set *ms, unsig
 			if (file_printf(ms, ", from '%.31s', pid=%u, uid=%u, "
 			    "gid=%u, nlwps=%u, lwp=%u (signal %u/code %u)",
 			    file_printable(sbuf, sizeof(sbuf),
-			    CAST(char *, pi.cpi_name)),
+			    RCAST(char *, pi.cpi_name), sizeof(pi.cpi_name)),
 			    elf_getu32(swap, pi.cpi_pid),
 			    elf_getu32(swap, pi.cpi_euid),
 			    elf_getu32(swap, pi.cpi_egid),
@@ -1564,7 +1564,8 @@ dophn_exec(struct magic_set *ms, int cla
 		return -1;
 	if (interp[0])
 		if (file_printf(ms, ", interpreter %s",
-		    file_printable(ibuf, sizeof(ibuf), interp)) == -1)
+		    file_printable(ibuf, sizeof(ibuf), interp, sizeof(interp)))
+			== -1)
 			return -1;
 	return 0;
 }
$NetBSD$

fix PR/62: spinpx: limit size of file_printable.  (CVE-2019-8904)

https://bugs.astron.com/view.php?id=62
https://github.com/file/file/commit/d65781527c8134a1202b2649695d48d5701ac60b

--- src/softmagic.c.orig	2019-02-19 10:57:44.000000000 +0000
+++ src/softmagic.c
@@ -546,8 +546,8 @@ mprint(struct magic_set *ms, struct magi
   	case FILE_LESTRING16:
 		if (m->reln == '=' || m->reln == '!') {
 			if (file_printf(ms, F(ms, m, "%s"), 
-			    file_printable(sbuf, sizeof(sbuf), m->value.s))
-			    == -1)
+			    file_printable(sbuf, sizeof(sbuf), m->value.s,
+			    sizeof(m->value.s))) == -1)
 				return -1;
 			t = ms->offset + m->vallen;
 		}
@@ -574,7 +574,8 @@ mprint(struct magic_set *ms, struct magi
 			}
 
 			if (file_printf(ms, F(ms, m, "%s"),
-			    file_printable(sbuf, sizeof(sbuf), str)) == -1)
+			    file_printable(sbuf, sizeof(sbuf), str,
+				sizeof(p->s) - (str - p->s))) == -1)
 				return -1;
 
 			if (m->type == FILE_PSTRING)
@@ -680,7 +681,7 @@ mprint(struct magic_set *ms, struct magi
 			return -1;
 		}
 		rval = file_printf(ms, F(ms, m, "%s"),
-		    file_printable(sbuf, sizeof(sbuf), cp));
+		    file_printable(sbuf, sizeof(sbuf), cp, ms->search.rm_len));
 		free(cp);
 
 		if (rval == -1)
@@ -707,7 +708,8 @@ mprint(struct magic_set *ms, struct magi
 		break;
 	case FILE_DER:
 		if (file_printf(ms, F(ms, m, "%s"), 
-		    file_printable(sbuf, sizeof(sbuf), ms->ms_value.s)) == -1)
+		    file_printable(sbuf, sizeof(sbuf), ms->ms_value.s,
+			sizeof(ms->ms_value.s))) == -1)
 			return -1;
 		t = ms->offset;
 		break;
@@ -1383,38 +1385,64 @@ mget(struct magic_set *ms, const unsigne
 	if (m->flag & INDIR) {
 		intmax_t off = m->in_offset;
 		const int sgn = m->in_op & FILE_OPSIGNED;
-		if (m->in_op & FILE_OPINDIRECT) {
-			const union VALUETYPE *q = CAST(const union VALUETYPE *,
-			    ((const void *)(s + offset + off)));
-			if (OFFSET_OOB(nbytes, offset + off, sizeof(*q)))
-				return 0;
-			switch (cvt_flip(m->in_type, flip)) {
-			case FILE_BYTE:
-				off = SEXT(sgn,8,q->b);
-				break;
-			case FILE_SHORT:
-				off = SEXT(sgn,16,q->h);
-				break;
-			case FILE_BESHORT:
-				off = SEXT(sgn,16,BE16(q));
-				break;
-			case FILE_LESHORT:
-				off = SEXT(sgn,16,LE16(q));
-				break;
-			case FILE_LONG:
-				off = SEXT(sgn,32,q->l);
-				break;
-			case FILE_BELONG:
-			case FILE_BEID3:
-				off = SEXT(sgn,32,BE32(q));
-				break;
-			case FILE_LEID3:
-			case FILE_LELONG:
-				off = SEXT(sgn,32,LE32(q));
-				break;
-			case FILE_MELONG:
-				off = SEXT(sgn,32,ME32(q));
-				break;
+ 		if (m->in_op & FILE_OPINDIRECT) {
+ 			const union VALUETYPE *q = CAST(const union VALUETYPE *,
+ 			    ((const void *)(s + offset + off)));
+ 			switch (cvt_flip(m->in_type, flip)) {
+ 			case FILE_BYTE:
+				if (OFFSET_OOB(nbytes, offset + off, 1))
+					return 0;
+ 				off = SEXT(sgn,8,q->b);
+ 				break;
+ 			case FILE_SHORT:
+				if (OFFSET_OOB(nbytes, offset + off, 2))
+					return 0;
+ 				off = SEXT(sgn,16,q->h);
+ 				break;
+ 			case FILE_BESHORT:
+				if (OFFSET_OOB(nbytes, offset + off, 2))
+					return 0;
+ 				off = SEXT(sgn,16,BE16(q));
+ 				break;
+ 			case FILE_LESHORT:
+				if (OFFSET_OOB(nbytes, offset + off, 2))
+					return 0;
+ 				off = SEXT(sgn,16,LE16(q));
+ 				break;
+ 			case FILE_LONG:
+				if (OFFSET_OOB(nbytes, offset + off, 4))
+					return 0;
+ 				off = SEXT(sgn,32,q->l);
+ 				break;
+ 			case FILE_BELONG:
+ 			case FILE_BEID3:
+				if (OFFSET_OOB(nbytes, offset + off, 4))
+					return 0;
+ 				off = SEXT(sgn,32,BE32(q));
+ 				break;
+ 			case FILE_LEID3:
+ 			case FILE_LELONG:
+				if (OFFSET_OOB(nbytes, offset + off, 4))
+					return 0;
+ 				off = SEXT(sgn,32,LE32(q));
+ 				break;
+ 			case FILE_MELONG:
+				if (OFFSET_OOB(nbytes, offset + off, 4))
+					return 0;
+ 				off = SEXT(sgn,32,ME32(q));
+ 				break;
+ 			case FILE_BEQUAD:
+				if (OFFSET_OOB(nbytes, offset + off, 8))
+					return 0;
+ 				off = SEXT(sgn,64,BE64(q));
+ 				break;
+ 			case FILE_LEQUAD:
+				if (OFFSET_OOB(nbytes, offset + off, 8))
+					return 0;
+ 				off = SEXT(sgn,64,LE64(q));
+ 				break;
+ 			default:
+                               abort();
 			}
 			if ((ms->flags & MAGIC_DEBUG) != 0)
 				fprintf(stderr, "indirect offs=%jd\n", off);


Home | Main Index | Thread Index | Old Index