Browse Source

Import several important commits post 5.25 release

FILE5_25-1-g7e60111 PR/479: check the format length modifiers.
FILE5_25-2-gde23336 PR/479: Protect against 0-divide and offset out of bounds reads.
FILE5_25-4-gc12b1c8 annotations are attached to the first description entry, print them then.
FILE5_25-6-gb72c33f remove over-zealous, and fix test properly.
FILE5_25-7-g1052fe4 drop the count of digits allowed.
FILE5_25-9-g9039ec5 Make the default case print something sane for each of the different styles: (...)
Christoph Biedl 8 years ago
parent
commit
5052822f64

+ 201 - 0
debian/patches/cherry-pick.FILE5_25-1-g7e60111.PR-479-check-the-format-length-modifiers.patch

@@ -0,0 +1,201 @@
+Subject: PR/479: check the format length modifiers
+Origin: FILE5_25-1-g7e60111
+Upstream-Author: Christos Zoulas <christos@zoulas.com>
+Date: Wed Sep 16 18:21:26 2015 +0000
+
+--- a/src/apprentice.c
++++ b/src/apprentice.c
+@@ -143,7 +143,7 @@
+ private void apprentice_unmap(struct magic_map *);
+ private int apprentice_compile(struct magic_set *, struct magic_map *,
+     const char *);
+-private int check_format_type(const char *, int);
++private int check_format_type(const char *, int, const char **);
+ private int check_format(struct magic_set *, struct magic *);
+ private int get_op(char);
+ private int parse_mime(struct magic_set *, struct magic_entry *, const char *);
+@@ -2298,11 +2298,13 @@
+ }
+ 
+ private int
+-check_format_type(const char *ptr, int type)
++check_format_type(const char *ptr, int type, const char **estr)
+ {
+ 	int quad = 0, h;
++	size_t len, cnt;
+ 	if (*ptr == '\0') {
+ 		/* Missing format string; bad */
++		*estr = "missing format spec";
+ 		return -1;
+ 	}
+ 
+@@ -2339,15 +2341,22 @@
+ 			ptr++;
+ 		if (*ptr == '.')
+ 			ptr++;
+-		while (isdigit((unsigned char)*ptr)) ptr++;
++#define CHECKLEN() do { \
++	for (len = cnt = 0; isdigit((unsigned char)*ptr); ptr++, cnt++) \
++		len = len * 10 + (*ptr - '0'); \
++	if (cnt > 10 || len > 1024) \
++		goto toolong; \
++} while (/*CONSTCOND*/0)
++
++		CHECKLEN();
+ 		if (*ptr == '.')
+ 			ptr++;
+-		while (isdigit((unsigned char)*ptr)) ptr++;
++		CHECKLEN();
+ 		if (quad) {
+ 			if (*ptr++ != 'l')
+-				return -1;
++				goto invalid;
+ 			if (*ptr++ != 'l')
+-				return -1;
++				goto invalid;
+ 		}
+ 	
+ 		switch (*ptr++) {
+@@ -2361,9 +2370,11 @@
+ 			case 'o':
+ 			case 'x':
+ 			case 'X':
+-				return h != 0 ? -1 : 0;
++				if (h == 0)
++					return 0;
++				/*FALLTHROUGH*/
+ 			default:
+-				return -1;
++				goto invalid;
+ 			}
+ 		
+ 		/*
+@@ -2372,11 +2383,11 @@
+ 		 */
+ 		case 'h':
+ 			if (h-- <= 0)
+-				return -1;
++				goto invalid;
+ 			switch (*ptr++) {
+ 			case 'h':
+ 				if (h-- <= 0)
+-					return -1;
++					goto invalid;
+ 				switch (*ptr++) {
+ 				case 'i':
+ 				case 'd':
+@@ -2386,7 +2397,7 @@
+ 				case 'X':
+ 					return 0;
+ 				default:
+-					return -1;
++					goto invalid;
+ 				}
+ 			case 'i':
+ 			case 'd':
+@@ -2394,13 +2405,17 @@
+ 			case 'o':
+ 			case 'x':
+ 			case 'X':
+-				return h != 0 ? -1 : 0;
++				if (h == 0)
++					return 0;
++				/*FALLTHROUGH*/
+ 			default:
+-				return -1;
++				goto invalid;
+ 			}
+ #endif
+ 		case 'c':
+-			return h != 2 ? -1 : 0;
++			if (h == 2)
++				return 0;
++			goto invalid;
+ 		case 'i':
+ 		case 'd':
+ 		case 'u':
+@@ -2408,12 +2423,14 @@
+ 		case 'x':
+ 		case 'X':
+ #ifdef STRICT_FORMAT
+-			return h != 0 ? -1 : 0;
++			if (h == 0)
++				return 0;
++			/*FALLTHROUGH*/
+ #else
+ 			return 0;
+ #endif
+ 		default:
+-			return -1;
++			goto invalid;
+ 		}
+ 		
+ 	case FILE_FMT_FLOAT:
+@@ -2422,11 +2439,10 @@
+ 			ptr++;
+ 		if (*ptr == '.')
+ 			ptr++;
+-		while (isdigit((unsigned char)*ptr)) ptr++;
++		CHECKLEN();
+ 		if (*ptr == '.')
+ 			ptr++;
+-		while (isdigit((unsigned char)*ptr)) ptr++;
+-	
++		CHECKLEN();
+ 		switch (*ptr++) {
+ 		case 'e':
+ 		case 'E':
+@@ -2437,7 +2453,7 @@
+ 			return 0;
+ 			
+ 		default:
+-			return -1;
++			goto invalid;
+ 		}
+ 		
+ 
+@@ -2456,14 +2472,17 @@
+ 		case 's':
+ 			return 0;
+ 		default:
+-			return -1;
++			goto invalid;
+ 		}
+ 		
+ 	default:
+ 		/* internal error */
+ 		abort();
+ 	}
+-	/*NOTREACHED*/
++invalid:
++	*estr = "not valid";
++toolong:
++	*estr = "too long";
+ 	return -1;
+ }
+ 	
+@@ -2475,6 +2494,7 @@
+ check_format(struct magic_set *ms, struct magic *m)
+ {
+ 	char *ptr;
++	const char *estr;
+ 
+ 	for (ptr = m->desc; *ptr; ptr++)
+ 		if (*ptr == '%')
+@@ -2498,13 +2518,13 @@
+ 	}
+ 
+ 	ptr++;
+-	if (check_format_type(ptr, m->type) == -1) {
++	if (check_format_type(ptr, m->type, &estr) == -1) {
+ 		/*
+ 		 * TODO: this error message is unhelpful if the format
+ 		 * string is not one character long
+ 		 */
+-		file_magwarn(ms, "Printf format `%c' is not valid for type "
+-		    "`%s' in description `%s'", *ptr ? *ptr : '?',
++		file_magwarn(ms, "Printf format is %s for type "
++		    "`%s' in description `%s'", estr,
+ 		    file_names[m->type], m->desc);
+ 		return -1;
+ 	}

+ 253 - 0
debian/patches/cherry-pick.FILE5_25-2-gde23336.PR-479-Protect-against-0-divide-and-offset-out-of-bounds-reads.patch

@@ -0,0 +1,253 @@
+Subject: PR/479: Protect against 0-divide and offset out of bounds reads
+Origin: FILE5_25-2-gde23336
+Upstream-Author: Christos Zoulas <christos@zoulas.com>
+Date: Wed Sep 16 18:25:23 2015 +0000
+
+--- a/src/softmagic.c
++++ b/src/softmagic.c
+@@ -57,10 +57,10 @@
+ private int mconvert(struct magic_set *, struct magic *, int);
+ private int print_sep(struct magic_set *, int);
+ private int handle_annotation(struct magic_set *, struct magic *);
+-private void cvt_8(union VALUETYPE *, const struct magic *);
+-private void cvt_16(union VALUETYPE *, const struct magic *);
+-private void cvt_32(union VALUETYPE *, const struct magic *);
+-private void cvt_64(union VALUETYPE *, const struct magic *);
++private int cvt_8(union VALUETYPE *, const struct magic *);
++private int cvt_16(union VALUETYPE *, const struct magic *);
++private int cvt_32(union VALUETYPE *, const struct magic *);
++private int cvt_64(union VALUETYPE *, const struct magic *);
+ 
+ #define OFFSET_OOB(n, o, i)	((n) < (o) || (i) > ((n) - (o)))
+ #define BE64(p) (((uint64_t)(p)->hq[0]<<56)|((uint64_t)(p)->hq[1]<<48)| \
+@@ -858,37 +858,45 @@
+ 			p->fld *= cast m->num_mask; \
+ 			break; \
+ 		case FILE_OPDIVIDE: \
++			if (cast m->num_mask == 0) \
++				return -1; \
+ 			p->fld /= cast m->num_mask; \
+ 			break; \
+ 		case FILE_OPMODULO: \
++			if (cast m->num_mask == 0) \
++				return -1; \
+ 			p->fld %= cast m->num_mask; \
+ 			break; \
+ 		} \
+ 	if (m->mask_op & FILE_OPINVERSE) \
+ 		p->fld = ~p->fld \
+ 
+-private void
++private int
+ cvt_8(union VALUETYPE *p, const struct magic *m)
+ {
+ 	DO_CVT(b, (uint8_t));
++	return 0;
+ }
+ 
+-private void
++private int
+ cvt_16(union VALUETYPE *p, const struct magic *m)
+ {
+ 	DO_CVT(h, (uint16_t));
++	return 0;
+ }
+ 
+-private void
++private int
+ cvt_32(union VALUETYPE *p, const struct magic *m)
+ {
+ 	DO_CVT(l, (uint32_t));
++	return 0;
+ }
+ 
+-private void
++private int
+ cvt_64(union VALUETYPE *p, const struct magic *m)
+ {
+ 	DO_CVT(q, (uint64_t));
++	return 0;
+ }
+ 
+ #define DO_CVT2(fld, cast) \
+@@ -904,20 +912,24 @@
+ 			p->fld *= cast m->num_mask; \
+ 			break; \
+ 		case FILE_OPDIVIDE: \
++			if (cast m->num_mask == 0) \
++				return -1; \
+ 			p->fld /= cast m->num_mask; \
+ 			break; \
+ 		} \
+ 
+-private void
++private int
+ cvt_float(union VALUETYPE *p, const struct magic *m)
+ {
+ 	DO_CVT2(f, (float));
++	return 0;
+ }
+ 
+-private void
++private int
+ cvt_double(union VALUETYPE *p, const struct magic *m)
+ {
+ 	DO_CVT2(d, (double));
++	return 0;
+ }
+ 
+ /*
+@@ -933,21 +945,25 @@
+ 
+ 	switch (type = cvt_flip(m->type, flip)) {
+ 	case FILE_BYTE:
+-		cvt_8(p, m);
++		if (cvt_8(p, m) == -1)
++			goto out;
+ 		return 1;
+ 	case FILE_SHORT:
+-		cvt_16(p, m);
++		if (cvt_16(p, m) == -1)
++			goto out;
+ 		return 1;
+ 	case FILE_LONG:
+ 	case FILE_DATE:
+ 	case FILE_LDATE:
+-		cvt_32(p, m);
++		if (cvt_32(p, m) == -1)
++			goto out;
+ 		return 1;
+ 	case FILE_QUAD:
+ 	case FILE_QDATE:
+ 	case FILE_QLDATE:
+ 	case FILE_QWDATE:
+-		cvt_64(p, m);
++		if (cvt_64(p, m) == -1)
++			goto out;
+ 		return 1;
+ 	case FILE_STRING:
+ 	case FILE_BESTRING16:
+@@ -979,65 +995,78 @@
+ 	}
+ 	case FILE_BESHORT:
+ 		p->h = (short)BE16(p);
+-		cvt_16(p, m);
++		if (cvt_16(p, m) == -1)
++			goto out;
+ 		return 1;
+ 	case FILE_BELONG:
+ 	case FILE_BEDATE:
+ 	case FILE_BELDATE:
+ 		p->l = (int32_t)BE32(p);
+-		cvt_32(p, m);
++		if (cvt_32(p, m) == -1)
++			goto out;
+ 		return 1;
+ 	case FILE_BEQUAD:
+ 	case FILE_BEQDATE:
+ 	case FILE_BEQLDATE:
+ 	case FILE_BEQWDATE:
+ 		p->q = (uint64_t)BE64(p);
+-		cvt_64(p, m);
++		if (cvt_64(p, m) == -1)
++			goto out;
+ 		return 1;
+ 	case FILE_LESHORT:
+ 		p->h = (short)LE16(p);
+-		cvt_16(p, m);
++		if (cvt_16(p, m) == -1)
++			goto out;
+ 		return 1;
+ 	case FILE_LELONG:
+ 	case FILE_LEDATE:
+ 	case FILE_LELDATE:
+ 		p->l = (int32_t)LE32(p);
+-		cvt_32(p, m);
++		if (cvt_32(p, m) == -1)
++			goto out;
+ 		return 1;
+ 	case FILE_LEQUAD:
+ 	case FILE_LEQDATE:
+ 	case FILE_LEQLDATE:
+ 	case FILE_LEQWDATE:
+ 		p->q = (uint64_t)LE64(p);
+-		cvt_64(p, m);
++		if (cvt_64(p, m) == -1)
++			goto out;
+ 		return 1;
+ 	case FILE_MELONG:
+ 	case FILE_MEDATE:
+ 	case FILE_MELDATE:
+ 		p->l = (int32_t)ME32(p);
+-		cvt_32(p, m);
++		if (cvt_32(p, m) == -1)
++			goto out;
+ 		return 1;
+ 	case FILE_FLOAT:
+-		cvt_float(p, m);
++		if (cvt_float(p, m) == -1)
++			goto out;
+ 		return 1;
+ 	case FILE_BEFLOAT:
+ 		p->l = BE32(p);
+-		cvt_float(p, m);
++		if (cvt_float(p, m) == -1)
++			goto out;
+ 		return 1;
+ 	case FILE_LEFLOAT:
+ 		p->l = LE32(p);
+-		cvt_float(p, m);
++		if (cvt_float(p, m) == -1)
++			goto out;
+ 		return 1;
+ 	case FILE_DOUBLE:
+-		cvt_double(p, m);
++		if (cvt_double(p, m) == -1)
++			goto out;
+ 		return 1;
+ 	case FILE_BEDOUBLE:
+ 		p->q = BE64(p); 
+-		cvt_double(p, m);
++		if (cvt_double(p, m) == -1)
++			goto out;
+ 		return 1;
+ 	case FILE_LEDOUBLE:
+ 		p->q = LE64(p);
+-		cvt_double(p, m);
++		if (cvt_double(p, m) == -1)
++			goto out;
+ 		return 1;
+ 	case FILE_REGEX:
+ 	case FILE_SEARCH:
+@@ -1050,6 +1079,9 @@
+ 		file_magerror(ms, "invalid type %d in mconvert()", m->type);
+ 		return 0;
+ 	}
++out:
++	file_magerror(ms, "zerodivide in mconvert()");
++	return 0;
+ }
+ 
+ 
+@@ -1066,6 +1098,12 @@
+ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
+     const unsigned char *s, uint32_t offset, size_t nbytes, struct magic *m)
+ {
++	if (offset >= nbytes) {
++		file_magerror(ms,
++		    "offset in magic %u greater than buffer size %zu",
++		    offset, nbytes);
++		return -1;
++	}
+ 	/*
+ 	 * Note: FILE_SEARCH and FILE_REGEX do not actually copy
+ 	 * anything, but setup pointers into the source
+@@ -1230,6 +1268,8 @@
+ 		if (m->in_op & FILE_OPINDIRECT) {
+ 			const union VALUETYPE *q = CAST(const union VALUETYPE *,
+ 			    ((const void *)(s + offset + off)));
++			if (OFFSET_OOB(offset + off, nbytes, sizeof(*q)))
++				return 0;
+ 			switch (cvt_flip(m->in_type, flip)) {
+ 			case FILE_BYTE:
+ 				off = q->b;

+ 63 - 0
debian/patches/cherry-pick.FILE5_25-4-gc12b1c8.annotations-are-attached-to-the-first-description-entry-print-them-then.patch

@@ -0,0 +1,63 @@
+Subject: annotations are attached to the first description entry, print them then
+Origin: FILE5_25-4-gc12b1c8
+Upstream-Author: Christos Zoulas <christos@zoulas.com>
+Date: Wed Sep 16 22:17:12 2015 +0000
+
+--- a/src/softmagic.c
++++ b/src/softmagic.c
+@@ -228,17 +228,17 @@
+ 			continue;
+ 		}
+ 
+-		if ((e = handle_annotation(ms, m)) != 0) {
+-			*need_separator = 1;
+-			*printed_something = 1;
+-			*returnval = 1;
+-			return e;
+-		}
+ 		/*
+ 		 * If we are going to print something, we'll need to print
+ 		 * a blank before we print something else.
+ 		 */
+ 		if (*m->desc) {
++			if ((e = handle_annotation(ms, m)) != 0) {
++				*need_separator = 1;
++				*printed_something = 1;
++				*returnval = 1;
++				return e;
++			}
+ 			*need_separator = 1;
+ 			*printed_something = 1;
+ 			if (print_sep(ms, firstline) == -1)
+@@ -318,17 +318,17 @@
+ 						break;
+ 				} else
+ 					ms->c.li[cont_level].got_match = 1;
+-				if ((e = handle_annotation(ms, m)) != 0) {
+-					*need_separator = 1;
+-					*printed_something = 1;
+-					*returnval = 1;
+-					return e;
+-				}
+ 				/*
+ 				 * If we are going to print something,
+ 				 * make sure that we have a separator first.
+ 				 */
+ 				if (*m->desc) {
++					if ((e = handle_annotation(ms, m)) != 0) {
++						*need_separator = 1;
++						*printed_something = 1;
++						*returnval = 1;
++						return e;
++					}
+ 					if (!*printed_something) {
+ 						*printed_something = 1;
+ 						if (print_sep(ms, firstline)
+@@ -2166,6 +2166,7 @@
+ private int
+ handle_annotation(struct magic_set *ms, struct magic *m)
+ {
++printf("desc = %s, ext = %s mime = %s\n", m->desc, m->ext, m->mimetype);
+ 	if (ms->flags & MAGIC_APPLE) {
+ 		if (file_printf(ms, "%.8s", m->apple) == -1)
+ 			return -1;

+ 37 - 0
debian/patches/cherry-pick.FILE5_25-6-gb72c33f.remove-over-zealous-and-fix-test-properly.patch

@@ -0,0 +1,37 @@
+Subject: remove over-zealous, and fix test properly
+Origin: FILE5_25-6-gb72c33f
+Upstream-Author: Christos Zoulas <christos@zoulas.com>
+Date: Wed Sep 16 22:37:05 2015 +0000
+
+--- a/src/softmagic.c
++++ b/src/softmagic.c
+@@ -1098,12 +1098,6 @@
+ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir,
+     const unsigned char *s, uint32_t offset, size_t nbytes, struct magic *m)
+ {
+-	if (offset >= nbytes) {
+-		file_magerror(ms,
+-		    "offset in magic %u greater than buffer size %zu",
+-		    offset, nbytes);
+-		return -1;
+-	}
+ 	/*
+ 	 * Note: FILE_SEARCH and FILE_REGEX do not actually copy
+ 	 * anything, but setup pointers into the source
+@@ -1268,7 +1262,7 @@
+ 		if (m->in_op & FILE_OPINDIRECT) {
+ 			const union VALUETYPE *q = CAST(const union VALUETYPE *,
+ 			    ((const void *)(s + offset + off)));
+-			if (OFFSET_OOB(offset + off, nbytes, sizeof(*q)))
++			if (OFFSET_OOB(nbytes, offset + off, sizeof(*q)))
+ 				return 0;
+ 			switch (cvt_flip(m->in_type, flip)) {
+ 			case FILE_BYTE:
+@@ -2166,7 +2160,6 @@
+ private int
+ handle_annotation(struct magic_set *ms, struct magic *m)
+ {
+-printf("desc = %s, ext = %s mime = %s\n", m->desc, m->ext, m->mimetype);
+ 	if (ms->flags & MAGIC_APPLE) {
+ 		if (file_printf(ms, "%.8s", m->apple) == -1)
+ 			return -1;

+ 16 - 0
debian/patches/cherry-pick.FILE5_25-7-g1052fe4.drop-the-count-of-digits-allowed.patch

@@ -0,0 +1,16 @@
+Subject: drop the count of digits allowed
+Origin: FILE5_25-7-g1052fe4
+Upstream-Author: Christos Zoulas <christos@zoulas.com>
+Date: Wed Sep 16 22:52:54 2015 +0000
+
+--- a/src/apprentice.c
++++ b/src/apprentice.c
+@@ -2344,7 +2344,7 @@
+ #define CHECKLEN() do { \
+ 	for (len = cnt = 0; isdigit((unsigned char)*ptr); ptr++, cnt++) \
+ 		len = len * 10 + (*ptr - '0'); \
+-	if (cnt > 10 || len > 1024) \
++	if (cnt > 5 || len > 1024) \
+ 		goto toolong; \
+ } while (/*CONSTCOND*/0)
+ 

+ 32 - 0
debian/patches/cherry-pick.FILE5_25-9-g9039ec5.make-the-default-case-print-something-sane-for-each-of-the-different-styles.patch

@@ -0,0 +1,32 @@
+Subject: Make the default case print something sane for each of the different styles: (...)
+Origin: FILE5_25-9-g9039ec5
+Upstream-Author: Christos Zoulas <christos@zoulas.com>
+Date: Thu Sep 17 01:10:51 2015 +0000
+
+    Make the default case print something sane for each of the different styles:
+    apple, mime, encoding, default. Before it just printed data which is confusing.
+
+--- a/src/funcs.c
++++ b/src/funcs.c
+@@ -293,9 +293,18 @@
+ simple:
+ 	/* give up */
+ 	m = 1;
+-	if ((!mime || (mime & MAGIC_MIME_TYPE)) &&
+-	    file_printf(ms, "%s", mime ? type : def) == -1) {
+-	    rv = -1;
++	if (ms->flags & MAGIC_MIME) {
++		if (file_printf(ms, "%s", type) == -1)
++			rv = -1;
++	} else if (ms->flags & MAGIC_APPLE) {
++		if (file_printf(ms, "UNKNUNKN") == -1)
++			rv = -1;
++	} else if (ms->flags & MAGIC_EXTENSION) {
++		if (file_printf(ms, "???") == -1)
++			rv = -1;
++	} else {
++		if (file_printf(ms, "%s", def) == -1)
++			rv = -1;
+ 	}
+  done:
+ 	if ((ms->flags & MAGIC_MIME_ENCODING) != 0) {

+ 6 - 0
debian/patches/series

@@ -1,5 +1,11 @@
 # cherry-picked commits. Keep in chronlogical order
+cherry-pick.FILE5_25-1-g7e60111.pr-479-check-the-format-length-modifiers.patch
+cherry-pick.FILE5_25-2-gde23336.pr-479-protect-against-0-divide-and-offset-out-of-bounds-reads.patch
+cherry-pick.FILE5_25-4-gc12b1c8.annotations-are-attached-to-the-first-description-entry-print-them-then.patch
 cherry-pick.FILE5_25-5-gba7b688.bump-more.patch
+cherry-pick.FILE5_25-6-gb72c33f.remove-over-zealous-and-fix-test-properly.patch
+cherry-pick.FILE5_25-7-g1052fe4.drop-the-count-of-digits-allowed.patch
+cherry-pick.FILE5_25-9-g9039ec5.make-the-default-case-print-something-sane-for-each-of-the-different-styles.patch
 
 # local modifications
 local.support-local-definitions-in-etc-magic.patch