Browse Source

Import upstream version 5.02

Christos Zoulas 15 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>
 2009-04-30  17:10  Christos Zoulas <christos@zoulas.com>
 
 
 	* Fix more cdf lossage. All the documents I have
 	* Fix more cdf lossage. All the documents I have

+ 10 - 10
configure

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

+ 2 - 0
magic/Magdir/python

@@ -14,6 +14,8 @@
 0	belong		0x3bf20d0a	python 2.3 byte-compiled
 0	belong		0x3bf20d0a	python 2.3 byte-compiled
 0	belong		0x6df20d0a	python 2.4 byte-compiled
 0	belong		0x6df20d0a	python 2.4 byte-compiled
 0	belong		0xb3f20d0a	python 2.5 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
 0	string/b  #!\ /usr/bin/python	python script text executable
 
 

+ 69 - 12
src/cdf.c

@@ -32,7 +32,7 @@
 #include "file.h"
 #include "file.h"
 
 
 #ifndef lint
 #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
 #endif
 
 
 #include <assert.h>
 #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",
 		DPRINTF(("Bad magic 0x%llx != 0x%llx\n",
 		    (unsigned long long)h->h_magic,
 		    (unsigned long long)h->h_magic,
 		    (unsigned long long)CDF_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;
 	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 i, j, k;
 	size_t ss = CDF_SEC_SIZE(h);
 	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;
 	size_t nsatpersec = (ss / sizeof(mid)) - 1;
 
 
 	for (i = 0; i < __arraycount(h->h_master_sat); i++)
 	for (i = 0; i < __arraycount(h->h_master_sat); i++)
 		if (h->h_master_sat[i] == CDF_SECID_FREE)
 		if (h->h_master_sat[i] == CDF_SECID_FREE)
 			break;
 			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));
 	DPRINTF(("sat_len = %zu ss = %zu\n", sat->sat_len, ss));
 	if ((sat->sat_tab = calloc(sat->sat_len, ss)) == NULL)
 	if ((sat->sat_tab = calloc(sat->sat_len, ss)) == NULL)
 		return -1;
 		return -1;
@@ -339,8 +359,19 @@ cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat)
 			goto out2;
 			goto out2;
 		}
 		}
 		for (k = 0; k < nsatpersec; k++, i++) {
 		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,
 			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",
 				DPRINTF(("Reading sector %d",
 				    CDF_TOLE4(msa[k])));
 				    CDF_TOLE4(msa[k])));
 				goto out2;
 				goto out2;
@@ -399,6 +430,17 @@ cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h,
 		return -1;
 		return -1;
 
 
 	for (j = i = 0; sid >= 0; i++, j++) {
 	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,
 		if ((nr = cdf_read_sector(info, scn->sst_tab, i * ss, ss, h,
 		    sid)) != (ssize_t)ss) {
 		    sid)) != (ssize_t)ss) {
 			if (i == scn->sst_len - 1 && nr > 0) {
 			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;
 			goto out;
 		}
 		}
 		sid = CDF_TOLE4(sat->sat_tab[sid]);
 		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;
 	return 0;
 out:
 out:
@@ -443,6 +480,12 @@ cdf_read_short_sector_chain(const cdf_header_t *h,
 			errno = EFTYPE;
 			errno = EFTYPE;
 			goto out;
 			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,
 		if (cdf_read_short_sector(sst, scn->sst_tab, i * ss, ss, h,
 		    sid) != (ssize_t)ss) {
 		    sid) != (ssize_t)ss) {
 			DPRINTF(("Reading short sector chain %d", sid));
 			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;
 			errno = EFTYPE;
 			goto out;
 			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) !=
 		if (cdf_read_sector(info, ssat->sat_tab, i * ss, ss, h, sid) !=
 		    (ssize_t)ss) {
 		    (ssize_t)ss) {
 			DPRINTF(("Reading short sat sector %d", sid));
 			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);
 	shp = (const void *)((const char *)sst->sst_tab + offs);
 	sh.sh_len = CDF_TOLE4(shp->sh_len);
 	sh.sh_len = CDF_TOLE4(shp->sh_len);
 	sh.sh_properties = CDF_TOLE4(shp->sh_properties);
 	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));
 	    sh.sh_properties));
 	if (*maxcount) {
 	if (*maxcount) {
+		if (*maxcount > CDF_PROP_LIM)
+			goto out;
 		*maxcount += sh.sh_properties;
 		*maxcount += sh.sh_properties;
 		inp = realloc(*info, *maxcount * sizeof(*inp));
 		inp = realloc(*info, *maxcount * sizeof(*inp));
 	} else {
 	} else {
@@ -713,6 +767,9 @@ cdf_read_property_info(const cdf_stream_t *sst, uint32_t offs,
 		case CDF_LENGTH32_STRING:
 		case CDF_LENGTH32_STRING:
 			if (nelements > 1) {
 			if (nelements > 1) {
 				size_t nelem = inp - *info;
 				size_t nelem = inp - *info;
+				if (*maxcount > CDF_PROP_LIM
+				    || nelements > CDF_PROP_LIM)
+					goto out;
 				*maxcount += nelements;
 				*maxcount += nelements;
 				inp = realloc(*info, *maxcount * sizeof(*inp));
 				inp = realloc(*info, *maxcount * sizeof(*inp));
 				if (inp == NULL)
 				if (inp == NULL)

+ 5 - 2
src/patchlevel.h

@@ -1,11 +1,14 @@
 #define	FILE_VERSION_MAJOR	5
 #define	FILE_VERSION_MAJOR	5
-#define	patchlevel		1
+#define	patchlevel		2
 
 
 /*
 /*
  * Patchlevel file for Ian Darwin's MAGIC command.
  * 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 $
  * $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
  * Revision 1.72  2009/04/30 21:20:15  christos
  * 5.01 we are almost here.
  * 5.01 we are almost here.
  *
  *

+ 4 - 3
src/readcdf.c

@@ -26,7 +26,7 @@
 #include "file.h"
 #include "file.h"
 
 
 #ifndef lint
 #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
 #endif
 
 
 #include <stdlib.h>
 #include <stdlib.h>
@@ -215,9 +215,9 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf,
 	cdf_dump_header(&h);
 	cdf_dump_header(&h);
 #endif
 #endif
 
 
-	if (cdf_read_sat(&info, &h, &sat) == -1) {
+	if ((i = cdf_read_sat(&info, &h, &sat)) == -1) {
 		expn = "Can't read SAT";
 		expn = "Can't read SAT";
-		return -1;
+		goto out0;
 	}
 	}
 #ifdef CDF_DEBUG
 #ifdef CDF_DEBUG
 	cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
 	cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h));
@@ -263,6 +263,7 @@ out2:
 	free(ssat.sat_tab);
 	free(ssat.sat_tab);
 out1:
 out1:
 	free(sat.sat_tab);
 	free(sat.sat_tab);
+out0:
 	if (i != 1) {
 	if (i != 1) {
 		if (file_printf(ms, "CDF V2 Document") == -1)
 		if (file_printf(ms, "CDF V2 Document") == -1)
 			return -1;
 			return -1;