Browse Source

Import upstream version 5.02

Christos Zoulas 10 years ago
parent
commit
26063b86d5
7 changed files with 95 additions and 28 deletions
  1. 4 0
      ChangeLog
  2. 10 10
      configure
  3. 1 1
      configure.ac
  4. 2 0
      magic/Magdir/python
  5. 69 12
      src/cdf.c
  6. 5 2
      src/patchlevel.h
  7. 4 3
      src/readcdf.c

+ 4 - 0
ChangeLog

@@ -1,3 +1,7 @@
+2009-05-01  18:37  Christos Zoulas <christos@zoulas.com>
+
+	* Buffer overflow fixes from Drew Yao
+
 2009-04-30  17:10  Christos Zoulas <christos@zoulas.com>
 
 	* Fix more cdf lossage. All the documents I have

+ 10 - 10
configure

@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for file 5.01.
+# Generated by GNU Autoconf 2.61 for file 5.02.
 #
 # Report bugs to <christos@astron.com>.
 #
@@ -728,8 +728,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='file'
 PACKAGE_TARNAME='file'
-PACKAGE_VERSION='5.01'
-PACKAGE_STRING='file 5.01'
+PACKAGE_VERSION='5.02'
+PACKAGE_STRING='file 5.02'
 PACKAGE_BUGREPORT='christos@astron.com'
 
 # Factoring default headers for most tests.
@@ -1399,7 +1399,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures file 5.01 to adapt to many kinds of systems.
+\`configure' configures file 5.02 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1469,7 +1469,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of file 5.01:";;
+     short | recursive ) echo "Configuration of file 5.02:";;
    esac
   cat <<\_ACEOF
 
@@ -1576,7 +1576,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-file configure 5.01
+file configure 5.02
 generated by GNU Autoconf 2.61
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1590,7 +1590,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by file $as_me 5.01, which was
+It was created by file $as_me 5.02, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   $ $0 $@
@@ -2280,7 +2280,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='file'
- VERSION='5.01'
+ VERSION='5.02'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -24303,7 +24303,7 @@ exec 6>&1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by file $as_me 5.01, which was
+This file was extended by file $as_me 5.02, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -24356,7 +24356,7 @@ Report bugs to <bug-autoconf@gnu.org>."
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-file config.status 5.01
+file config.status 5.02
 configured by $0, generated by GNU Autoconf 2.61,
   with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 

+ 1 - 1
configure.ac

@@ -1,5 +1,5 @@
 dnl Process this file with autoconf to produce a configure script.
-AC_INIT(file, 5.01, christos@astron.com)
+AC_INIT(file, 5.02, christos@astron.com)
 AM_INIT_AUTOMAKE
 AM_CONFIG_HEADER(config.h)
 #AC_CONFIG_MACRO_DIR([m4])

+ 2 - 0
magic/Magdir/python

@@ -14,6 +14,8 @@
 0	belong		0x3bf20d0a	python 2.3 byte-compiled
 0	belong		0x6df20d0a	python 2.4 byte-compiled
 0	belong		0xb3f20d0a	python 2.5 byte-compiled
+0	belong		0xd1f20d0a	python 2.6 byte-compiled
+
 
 0	string/b  #!\ /usr/bin/python	python script text executable
 

+ 69 - 12
src/cdf.c

@@ -32,7 +32,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: cdf.c,v 1.22 2009/04/30 21:03:26 christos Exp $")
+FILE_RCSID("@(#)$File: cdf.c,v 1.26 2009/05/02 20:06:55 christos Exp $")
 #endif
 
 #include <assert.h>
@@ -268,10 +268,21 @@ cdf_read_header(const cdf_info_t *info, cdf_header_t *h)
 		DPRINTF(("Bad magic 0x%llx != 0x%llx\n",
 		    (unsigned long long)h->h_magic,
 		    (unsigned long long)CDF_MAGIC));
-		errno = EFTYPE;
-		return -1;
+		goto out;
+	}
+	if (h->h_sec_size_p2 > 20) {
+		DPRINTF(("Bad sector size 0x%u\n", h->h_sec_size_p2));
+		goto out;
+	}
+	if (h->h_short_sec_size_p2 > 20) {
+		DPRINTF(("Bad short sector size 0x%u\n",
+		    h->h_short_sec_size_p2));
+		goto out;
 	}
 	return 0;
+out:
+	errno = EFTYPE;
+	return -1;
 }
 
 
@@ -302,14 +313,23 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat)
 {
 	size_t i, j, k;
 	size_t ss = CDF_SEC_SIZE(h);
-	cdf_secid_t *msa, mid;
+	cdf_secid_t *msa, mid, sec;
 	size_t nsatpersec = (ss / sizeof(mid)) - 1;
 
 	for (i = 0; i < __arraycount(h->h_master_sat); i++)
 		if (h->h_master_sat[i] == CDF_SECID_FREE)
 			break;
 
-	sat->sat_len = h->h_num_sectors_in_master_sat + i;
+#define CDF_SEC_LIMIT (UINT32_MAX / (4 * ss))
+	if (h->h_num_sectors_in_master_sat > CDF_SEC_LIMIT ||
+	    i > CDF_SEC_LIMIT / nsatpersec) {
+		DPRINTF(("Number of sectors in master SAT too big %u %zu\n",
+		    h->h_num_sectors_in_master_sat, i));
+		errno = EFTYPE;
+		return -1;
+	}
+
+	sat->sat_len = h->h_num_sectors_in_master_sat + i * nsatpersec;
 	DPRINTF(("sat_len = %zu ss = %zu\n", sat->sat_len, ss));
 	if ((sat->sat_tab = calloc(sat->sat_len, ss)) == NULL)
 		return -1;
@@ -339,8 +359,19 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat)
 			goto out2;
 		}
 		for (k = 0; k < nsatpersec; k++, i++) {
+			sec = CDF_TOLE4(msa[k]);
+			if (sec < 0) {
+				sat->sat_len = i;
+				break;
+			}
+			if (i >= sat->sat_len) {
+			    DPRINTF(("Out of bounds reading MSA %u >= %u",
+				i, sat->sat_len));
+			    errno = EFTYPE;
+			    goto out2;
+			}
 			if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h,
-			    CDF_TOLE4(msa[k])) != (ssize_t)ss) {
+			    sec) != (ssize_t)ss) {
 				DPRINTF(("Reading sector %d",
 				    CDF_TOLE4(msa[k])));
 				goto out2;
@@ -399,6 +430,17 @@ cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
 		return -1;
 
 	for (j = i = 0; sid >= 0; i++, j++) {
+		if (j >= CDF_LOOP_LIMIT) {
+			DPRINTF(("Read long sector chain loop limit"));
+			errno = EFTYPE;
+			goto out;
+		}
+		if (i >= scn->sst_len) {
+			DPRINTF(("Out of bounds reading long sector chain "
+			    "%u > %u\n", i, scn->sst_len));
+			errno = EFTYPE;
+			goto out;
+		}
 		if ((nr = cdf_read_sector(info, scn->sst_tab, i * ss, ss, h,
 		    sid)) != (ssize_t)ss) {
 			if (i == scn->sst_len - 1 && nr > 0) {
@@ -409,11 +451,6 @@ cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
 			goto out;
 		}
 		sid = CDF_TOLE4(sat->sat_tab[sid]);
-		if (j >= CDF_LOOP_LIMIT) {
-			DPRINTF(("Read long sector chain loop limit"));
-			errno = EFTYPE;
-			goto out;
-		}
 	}
 	return 0;
 out:
@@ -443,6 +480,12 @@ cdf_read_short_sector_chain(const cdf_header_t *h,
 			errno = EFTYPE;
 			goto out;
 		}
+		if (i >= scn->sst_len) {
+			DPRINTF(("Out of bounds reading short sector chain "
+			    "%u > %u\n", i, scn->sst_len));
+			errno = EFTYPE;
+			goto out;
+		}
 		if (cdf_read_short_sector(sst, scn->sst_tab, i * ss, ss, h,
 		    sid) != (ssize_t)ss) {
 			DPRINTF(("Reading short sector chain %d", sid));
@@ -544,6 +587,12 @@ cdf_read_ssat(const cdf_info_t *info, const cdf_header_t *h,
 			errno = EFTYPE;
 			goto out;
 		}
+		if (i >= ssat->sat_len) {
+			DPRINTF(("Out of bounds reading short sector chain "
+			    "%u > %u\n", i, ssat->sat_len));
+			errno = EFTYPE;
+			goto out;
+		}
 		if (cdf_read_sector(info, ssat->sat_tab, i * ss, ss, h, sid) !=
 		    (ssize_t)ss) {
 			DPRINTF(("Reading short sat sector %d", sid));
@@ -640,9 +689,14 @@ cdf_read_property_info(const cdf_stream_t *sst, uint32_t offs,
 	shp = (const void *)((const char *)sst->sst_tab + offs);
 	sh.sh_len = CDF_TOLE4(shp->sh_len);
 	sh.sh_properties = CDF_TOLE4(shp->sh_properties);
-	DPRINTF(("section len: %d properties %d\n", sh.sh_len,
+#define CDF_PROP_LIM (UINT32_MAX / (4 * sizeof(*inp)))
+	if (sh.sh_properties > CDF_PROP_LIM)
+		goto out;
+	DPRINTF(("section len: %u properties %u\n", sh.sh_len,
 	    sh.sh_properties));
 	if (*maxcount) {
+		if (*maxcount > CDF_PROP_LIM)
+			goto out;
 		*maxcount += sh.sh_properties;
 		inp = realloc(*info, *maxcount * sizeof(*inp));
 	} else {
@@ -713,6 +767,9 @@ cdf_read_property_info(const cdf_stream_t *sst, uint32_t offs,
 		case CDF_LENGTH32_STRING:
 			if (nelements > 1) {
 				size_t nelem = inp - *info;
+				if (*maxcount > CDF_PROP_LIM
+				    || nelements > CDF_PROP_LIM)
+					goto out;
 				*maxcount += nelements;
 				inp = realloc(*info, *maxcount * sizeof(*inp));
 				if (inp == NULL)

+ 5 - 2
src/patchlevel.h

@@ -1,11 +1,14 @@
 #define	FILE_VERSION_MAJOR	5
-#define	patchlevel		1
+#define	patchlevel		2
 
 /*
  * Patchlevel file for Ian Darwin's MAGIC command.
- * $File: patchlevel.h,v 1.72 2009/04/30 21:20:15 christos Exp $
+ * $File: patchlevel.h,v 1.73 2009/05/04 15:15:13 christos Exp $
  *
  * $Log: patchlevel.h,v $
+ * Revision 1.73  2009/05/04 15:15:13  christos
+ * 5.02...
+ *
  * Revision 1.72  2009/04/30 21:20:15  christos
  * 5.01 we are almost here.
  *

+ 4 - 3
src/readcdf.c

@@ -26,7 +26,7 @@
 #include "file.h"
 
 #ifndef lint
-FILE_RCSID("@(#)$File: readcdf.c,v 1.15 2009/04/30 21:03:26 christos Exp $")
+FILE_RCSID("@(#)$File: readcdf.c,v 1.16 2009/05/01 22:36:58 christos Exp $")
 #endif
 
 #include <stdlib.h>
@@ -215,9 +215,9 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf,
 	cdf_dump_header(&h);
 #endif
 
-	if (cdf_read_sat(&info, &h, &sat) == -1) {
+	if ((i = cdf_read_sat(&info, &h, &sat)) == -1) {
 		expn = "Can't read SAT";
-		return -1;
+		goto out0;
 	}
 #ifdef CDF_DEBUG
 	cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
@@ -263,6 +263,7 @@ out2:
 	free(ssat.sat_tab);
 out1:
 	free(sat.sat_tab);
+out0:
 	if (i != 1) {
 		if (file_printf(ms, "CDF V2 Document") == -1)
 			return -1;