| 
					
				 | 
			
			
				@@ -0,0 +1,103 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Subject: file does not properly restrict the amount of data read during a regex search 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ID: CVE-2014-3538 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Author: Christos Zoulas <christos@zoulas.com> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Date: Tue Jun 3 19:01:34 2014 +0000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Origin: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    commit 4a284c89d6ef11aca34da65da7d673050a5ea320 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Debian-Author: Christoph Biedl <debian.axhn@manchmal.in-ulm.de> 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Comment: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ Taken from the fix in php5 (5.4.4-14+deb7u13), with minor corrections. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+Last-Update: 2014-09-07 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    * Enforce limit of 8K on regex searches that have no limits 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    * Allow the l modifier for regex to mean line count. Default 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      to byte count. If line count is specified, assume a max 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      of 80 characters per line to limit the byte count. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    * Don't allow conversions to be used for dates, allowing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      the mask field to be used as an offset. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    * Bump the version of the magic format so that regex changes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      are visible. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+--- a/src/softmagic.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++++ b/src/softmagic.c 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -51,7 +51,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ private int32_t moffset(struct magic_set *, struct magic *); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ private void mdebug(uint32_t, const char *, size_t); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ private int mcopy(struct magic_set *, union VALUETYPE *, int, int, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-    const unsigned char *, uint32_t, size_t, size_t); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    const unsigned char *, uint32_t, size_t, struct magic *); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ private int mconvert(struct magic_set *, struct magic *); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ private int print_sep(struct magic_set *, int); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ private int handle_annotation(struct magic_set *, struct magic *); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -918,7 +918,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ private int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ mcopy(struct magic_set *ms, union VALUETYPE *p, int type, int indir, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-    const unsigned char *s, uint32_t offset, size_t nbytes, size_t linecnt) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++    const unsigned char *s, uint32_t offset, size_t nbytes, struct magic *m) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	 * Note: FILE_SEARCH and FILE_REGEX do not actually copy 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -938,15 +938,24 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			const char *last;	/* end of search region */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			const char *buf;	/* start of search region */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			const char *end; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-			size_t lines; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			size_t lines, linecnt, bytecnt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			linecnt = m->str_range; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			bytecnt = linecnt * 80; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			if (bytecnt == 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				bytecnt = 8192; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			if (bytecnt > nbytes) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				bytecnt = nbytes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			if (s == NULL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 				ms->search.s_len = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 				ms->search.s = NULL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 				return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			buf = RCAST(const char *, s) + offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-			end = last = RCAST(const char *, s) + nbytes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++			end = last = RCAST(const char *, s) + bytecnt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			/* mget() guarantees buf <= last */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			for (lines = linecnt, b = buf; lines && b < end && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			     ((b = CAST(const char *, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -959,7 +968,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 					b++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			if (lines) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-				last = RCAST(const char *, s) + nbytes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++				last = RCAST(const char *, s) + bytecnt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			ms->search.s = buf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			ms->search.s_len = last - buf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -1032,7 +1041,6 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     int recursion_level) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	uint32_t offset = ms->offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	uint32_t count = m->str_range; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	union VALUETYPE *p = &ms->ms_value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         if (recursion_level >= 20) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -1040,7 +1048,8 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-	if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, nbytes, count) == -1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	if (mcopy(ms, p, m->type, m->flag & INDIR, s, offset, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++	    (uint32_t)nbytes, m) == -1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 	if ((ms->flags & MAGIC_DEBUG) != 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+@@ -1527,7 +1536,7 @@ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		if (m->flag & INDIROFFADD) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			offset += ms->c.li[cont_level-1].off; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+-		if (mcopy(ms, p, m->type, 0, s, offset, nbytes, count) == -1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				++		if (mcopy(ms, p, m->type, 0, s, offset, nbytes, m) == -1) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 			return -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 		ms->offset = offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  
			 |