af9dc8
From a33759fd275b32ed0bbe89796fe2953b3cb0b41f Mon Sep 17 00:00:00 2001
af9dc8
From: Remi Collet <remi@php.net>
af9dc8
Date: Tue, 4 Mar 2014 20:32:52 +0100
af9dc8
Subject: [PATCH] Fixed Bug #66820 out-of-bounds memory access in fileinfo
af9dc8
af9dc8
Upstream fix:
af9dc8
https://github.com/glensc/file/commit/447558595a3650db2886cd2f416ad0beba965801
af9dc8
af9dc8
Notice, test changed, with upstream agreement:
af9dc8
-define OFFSET_OOB(n, o, i)	((n) < (o) || (i) >= ((n) - (o)))
af9dc8
+define OFFSET_OOB(n, o, i)	((n) < (o) || (i) >  ((n) - (o)))
af9dc8
---
af9dc8
 ext/fileinfo/libmagic/softmagic.c | 34 ++++++++++++++++++----------------
af9dc8
 1 file changed, 18 insertions(+), 16 deletions(-)
af9dc8
af9dc8
diff --git a/ext/fileinfo/libmagic/softmagic.c b/ext/fileinfo/libmagic/softmagic.c
af9dc8
index 82a470a..21fea6b 100644
af9dc8
--- a/ext/fileinfo/libmagic/softmagic.c
af9dc8
+++ b/ext/fileinfo/libmagic/softmagic.c
af9dc8
@@ -67,6 +67,8 @@ private void cvt_16(union VALUETYPE *, const struct magic *);
af9dc8
 private void cvt_32(union VALUETYPE *, const struct magic *);
af9dc8
 private void cvt_64(union VALUETYPE *, const struct magic *);
af9dc8
 
af9dc8
+#define OFFSET_OOB(n, o, i)	((n) < (o) || (i) > ((n) - (o)))
af9dc8
+
af9dc8
 /*
af9dc8
  * softmagic - lookup one file in parsed, in-memory copy of database
af9dc8
  * Passed the name and FILE * of one file to be typed.
af9dc8
@@ -1171,7 +1173,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
af9dc8
 		}
af9dc8
 		switch (cvt_flip(m->in_type, flip)) {
af9dc8
 		case FILE_BYTE:
af9dc8
-			if (nbytes < (offset + 1))
af9dc8
+			if (OFFSET_OOB(nbytes, offset, 1))
af9dc8
 				return 0;
af9dc8
 			if (off) {
af9dc8
 				switch (m->in_op & FILE_OPS_MASK) {
af9dc8
@@ -1206,7 +1208,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
af9dc8
 				offset = ~offset;
af9dc8
 			break;
af9dc8
 		case FILE_BESHORT:
af9dc8
-			if (nbytes < (offset + 2))
af9dc8
+			if (OFFSET_OOB(nbytes, offset, 2))
af9dc8
 				return 0;
af9dc8
 			if (off) {
af9dc8
 				switch (m->in_op & FILE_OPS_MASK) {
af9dc8
@@ -1258,7 +1260,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
af9dc8
 				offset = ~offset;
af9dc8
 			break;
af9dc8
 		case FILE_LESHORT:
af9dc8
-			if (nbytes < (offset + 2))
af9dc8
+			if (OFFSET_OOB(nbytes, offset, 2))
af9dc8
 				return 0;
af9dc8
 			if (off) {
af9dc8
 				switch (m->in_op & FILE_OPS_MASK) {
af9dc8
@@ -1310,7 +1312,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
af9dc8
 				offset = ~offset;
af9dc8
 			break;
af9dc8
 		case FILE_SHORT:
af9dc8
-			if (nbytes < (offset + 2))
af9dc8
+			if (OFFSET_OOB(nbytes, offset, 2))
af9dc8
 				return 0;
af9dc8
 			if (off) {
af9dc8
 				switch (m->in_op & FILE_OPS_MASK) {
af9dc8
@@ -1347,7 +1349,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
af9dc8
 			break;
af9dc8
 		case FILE_BELONG:
af9dc8
 		case FILE_BEID3:
af9dc8
-			if (nbytes < (offset + 4))
af9dc8
+			if (OFFSET_OOB(nbytes, offset, 4))
af9dc8
 				return 0;
af9dc8
 			if (off) {
af9dc8
 				switch (m->in_op & FILE_OPS_MASK) {
af9dc8
@@ -1418,7 +1420,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
af9dc8
 			break;
af9dc8
 		case FILE_LELONG:
af9dc8
 		case FILE_LEID3:
af9dc8
-			if (nbytes < (offset + 4))
af9dc8
+			if (OFFSET_OOB(nbytes, offset, 4))
af9dc8
 				return 0;
af9dc8
 			if (off) {
af9dc8
 				switch (m->in_op & FILE_OPS_MASK) {
af9dc8
@@ -1488,7 +1490,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
af9dc8
 				offset = ~offset;
af9dc8
 			break;
af9dc8
 		case FILE_MELONG:
af9dc8
-			if (nbytes < (offset + 4))
af9dc8
+			if (OFFSET_OOB(nbytes, offset, 4))
af9dc8
 				return 0;
af9dc8
 			if (off) {
af9dc8
 				switch (m->in_op & FILE_OPS_MASK) {
af9dc8
@@ -1558,7 +1560,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
af9dc8
 				offset = ~offset;
af9dc8
 			break;
af9dc8
 		case FILE_LONG:
af9dc8
-			if (nbytes < (offset + 4))
af9dc8
+			if (OFFSET_OOB(nbytes, offset, 4))
af9dc8
 				return 0;
af9dc8
 			if (off) {
af9dc8
 				switch (m->in_op & FILE_OPS_MASK) {
af9dc8
@@ -1630,14 +1632,14 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
af9dc8
 	/* Verify we have enough data to match magic type */
af9dc8
 	switch (m->type) {
af9dc8
 	case FILE_BYTE:
af9dc8
-		if (nbytes < (offset + 1)) /* should alway be true */
af9dc8
+		if (OFFSET_OOB(nbytes, offset, 1))
af9dc8
 			return 0;
af9dc8
 		break;
af9dc8
 
af9dc8
 	case FILE_SHORT:
af9dc8
 	case FILE_BESHORT:
af9dc8
 	case FILE_LESHORT:
af9dc8
-		if (nbytes < (offset + 2))
af9dc8
+		if (OFFSET_OOB(nbytes, offset, 2))
af9dc8
 			return 0;
af9dc8
 		break;
af9dc8
 
af9dc8
@@ -1656,33 +1658,33 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
af9dc8
 	case FILE_FLOAT:
af9dc8
 	case FILE_BEFLOAT:
af9dc8
 	case FILE_LEFLOAT:
af9dc8
-		if (nbytes < (offset + 4))
af9dc8
+		if (OFFSET_OOB(nbytes, offset, 4))
af9dc8
 			return 0;
af9dc8
 		break;
af9dc8
 
af9dc8
 	case FILE_DOUBLE:
af9dc8
 	case FILE_BEDOUBLE:
af9dc8
 	case FILE_LEDOUBLE:
af9dc8
-		if (nbytes < (offset + 8))
af9dc8
+		if (OFFSET_OOB(nbytes, offset, 8))
af9dc8
 			return 0;
af9dc8
 		break;
af9dc8
 
af9dc8
 	case FILE_STRING:
af9dc8
 	case FILE_PSTRING:
af9dc8
 	case FILE_SEARCH:
af9dc8
-		if (nbytes < (offset + m->vallen))
af9dc8
+		if (OFFSET_OOB(nbytes, offset, m->vallen))
af9dc8
 			return 0;
af9dc8
 		break;
af9dc8
 
af9dc8
 	case FILE_REGEX:
af9dc8
-		if (nbytes < offset)
af9dc8
+		if (OFFSET_OOB(nbytes, offset, 0))
af9dc8
 			return 0;
af9dc8
 		break;
af9dc8
 
af9dc8
 	case FILE_INDIRECT:
af9dc8
 		if (offset == 0)
af9dc8
 			return 0;
af9dc8
-		if (nbytes < offset)
af9dc8
+		if (OFFSET_OOB(nbytes, offset, 0))
af9dc8
 			return 0;
af9dc8
 		sbuf = ms->o.buf;
af9dc8
 		soffset = ms->offset;
af9dc8
@@ -1716,7 +1718,7 @@ mget(struct magic_set *ms, const unsigned char *s, struct magic *m,
af9dc8
 		return rv;
af9dc8
 
af9dc8
 	case FILE_USE:
af9dc8
-		if (nbytes < offset)
af9dc8
+		if (OFFSET_OOB(nbytes, offset, 0))
af9dc8
 			return 0;
af9dc8
 		sbuf = m->value.s;
af9dc8
 		if (*sbuf == '^') {
af9dc8
-- 
af9dc8
1.8.4.3
af9dc8