   Author: Janek Walkenhorst <walkenhorst@univention.de>

    CVE-2014-2270.patch

   From: Remi Collet <remi@php.net>
   Date: Tue, 4 Mar 2014 19:32:52 +0000 (+0100)
   Subject: Fixed Bug #66820 out-of-bounds memory access in fileinfo
   X-Git-Tag: php-5.4.27RC1~14
   X-Git-Url: http://72.52.91.13:8000/?p=php-src.git;a=commitdiff_plain;h=a33759fd275b32ed0bbe89796fe2953b3cb0b41f
   
   Fixed Bug #66820 out-of-bounds memory access in fileinfo
   
   Upstream fix:
   https://github.com/glensc/file/commit/447558595a3650db2886cd2f416ad0beba965801

   Notice, test changed, with upstream agreement:
   -define OFFSET_OOB(n, o, i)	((n) < (o) || (i) >= ((n) - (o)))
   +define OFFSET_OOB(n, o, i)	((n) < (o) || (i) >  ((n) - (o)))
---

Index: php5-5.3.3/ext/fileinfo/libmagic/softmagic.c
===================================================================
--- php5-5.3.3.orig/ext/fileinfo/libmagic/softmagic.c	2015-01-21 08:52:49.000000000 +0100
+++ php5-5.3.3/ext/fileinfo/libmagic/softmagic.c	2015-01-21 08:52:49.000000000 +0100
@@ -65,6 +65,8 @@
 private void cvt_32(union VALUETYPE *, const struct magic *);
 private void cvt_64(union VALUETYPE *, const struct magic *);
 
+#define OFFSET_OOB(n, o, i)	((n) < (o) || (i) > ((n) - (o)))
+
 /*
  * softmagic - lookup one file in parsed, in-memory copy of database
  * Passed the name and FILE * of one file to be typed.
@@ -1069,7 +1071,7 @@
 		}
 		switch (m->in_type) {
 		case FILE_BYTE:
-			if (nbytes < (offset + 1))
+			if (OFFSET_OOB(nbytes, offset, 1))
 				return 0;
 			if (off) {
 				switch (m->in_op & FILE_OPS_MASK) {
@@ -1104,7 +1106,7 @@
 				offset = ~offset;
 			break;
 		case FILE_BESHORT:
-			if (nbytes < (offset + 2))
+			if (OFFSET_OOB(nbytes, offset, 2))
 				return 0;
 			if (off) {
 				switch (m->in_op & FILE_OPS_MASK) {
@@ -1156,7 +1158,7 @@
 				offset = ~offset;
 			break;
 		case FILE_LESHORT:
-			if (nbytes < (offset + 2))
+			if (OFFSET_OOB(nbytes, offset, 2))
 				return 0;
 			if (off) {
 				switch (m->in_op & FILE_OPS_MASK) {
@@ -1208,7 +1210,7 @@
 				offset = ~offset;
 			break;
 		case FILE_SHORT:
-			if (nbytes < (offset + 2))
+			if (OFFSET_OOB(nbytes, offset, 2))
 				return 0;
 			if (off) {
 				switch (m->in_op & FILE_OPS_MASK) {
@@ -1245,7 +1247,7 @@
 			break;
 		case FILE_BELONG:
 		case FILE_BEID3:
-			if (nbytes < (offset + 4))
+			if (OFFSET_OOB(nbytes, offset, 4))
 				return 0;
 			if (off) {
 				switch (m->in_op & FILE_OPS_MASK) {
@@ -1316,7 +1318,7 @@
 			break;
 		case FILE_LELONG:
 		case FILE_LEID3:
-			if (nbytes < (offset + 4))
+			if (OFFSET_OOB(nbytes, offset, 4))
 				return 0;
 			if (off) {
 				switch (m->in_op & FILE_OPS_MASK) {
@@ -1386,7 +1388,7 @@
 				offset = ~offset;
 			break;
 		case FILE_MELONG:
-			if (nbytes < (offset + 4))
+			if (OFFSET_OOB(nbytes, offset, 4))
 				return 0;
 			if (off) {
 				switch (m->in_op & FILE_OPS_MASK) {
@@ -1456,7 +1458,7 @@
 				offset = ~offset;
 			break;
 		case FILE_LONG:
-			if (nbytes < (offset + 4))
+			if (OFFSET_OOB(nbytes, offset, 4))
 				return 0;
 			if (off) {
 				switch (m->in_op & FILE_OPS_MASK) {
@@ -1520,14 +1522,14 @@
 	/* Verify we have enough data to match magic type */
 	switch (m->type) {
 	case FILE_BYTE:
-		if (nbytes < (offset + 1)) /* should alway be true */
+		if (OFFSET_OOB(nbytes, offset, 1))
 			return 0;
 		break;
 
 	case FILE_SHORT:
 	case FILE_BESHORT:
 	case FILE_LESHORT:
-		if (nbytes < (offset + 2))
+		if (OFFSET_OOB(nbytes, offset, 2))
 			return 0;
 		break;
 
@@ -1546,26 +1548,26 @@
 	case FILE_FLOAT:
 	case FILE_BEFLOAT:
 	case FILE_LEFLOAT:
-		if (nbytes < (offset + 4))
+		if (OFFSET_OOB(nbytes, offset, 4))
 			return 0;
 		break;
 
 	case FILE_DOUBLE:
 	case FILE_BEDOUBLE:
 	case FILE_LEDOUBLE:
-		if (nbytes < (offset + 8))
+		if (OFFSET_OOB(nbytes, offset, 8))
 			return 0;
 		break;
 
 	case FILE_STRING:
 	case FILE_PSTRING:
 	case FILE_SEARCH:
-		if (nbytes < (offset + m->vallen))
+		if (OFFSET_OOB(nbytes, offset, m->vallen))
 			return 0;
 		break;
 
 	case FILE_REGEX:
-		if (nbytes < offset)
+		if (OFFSET_OOB(nbytes, offset, 0))
 			return 0;
 		break;
 
@@ -1575,7 +1577,7 @@
 	  	if ((ms->flags & (MAGIC_MIME|MAGIC_APPLE)) == 0 &&
 		    file_printf(ms, m->desc) == -1)
 			return -1;
-		if (nbytes < offset)
+		if (OFFSET_OOB(nbytes, offset, 0))
 			return 0;
 		return file_softmagic(ms, s + offset, nbytes - offset,
 		    recursion_level, BINTEST);
