diff usr/src/uts/common/fs/hsfs/hsfs_vfsops.c @ 494:e082e44c7fce

6244328 hsfs not resistant against malformed ISO9660 filesystems, crashes/hangs
author frankho
date Wed, 07 Sep 2005 05:57:46 -0700
parents 68f95e015346
children 1aef26bcfa0e
line wrap: on
line diff
--- a/usr/src/uts/common/fs/hsfs/hsfs_vfsops.c	Wed Sep 07 04:40:39 2005 -0700
+++ b/usr/src/uts/common/fs/hsfs/hsfs_vfsops.c	Wed Sep 07 05:57:46 2005 -0700
@@ -20,7 +20,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -466,22 +466,31 @@
 	struct buf	*bp;
 	int		error;
 	int		fsid;
-	int		size = CHECKSUM_SIZE;
 
 	secno = hsvp->root_dir.ext_lbn >> hsvp->lbn_secshift;
-	bp = bread(devvp->v_rdev, secno * 4, size);
+	bp = bread(devvp->v_rdev, secno * 4, CHECKSUM_SIZE);
 	error = geterror(bp);
-	if (!error) {
+
+	/*
+	 * An error on read or a partial read means we asked
+	 * for a nonexistant/corrupted piece of the device
+	 * (including past-the-end of the media). Don't
+	 * try to use the checksumming method then.
+	 */
+	if (!error && bp->b_bcount == CHECKSUM_SIZE) {
 		int *ibuf = (int *)bp->b_un.b_addr;
-		int isize = size / sizeof (int);
 		int i;
 
 		fsid = 0;
 
-		for (i = 0; i < isize; i++)
+		for (i = 0; i < CHECKSUM_SIZE / sizeof (int); i++)
 			fsid ^= ibuf[ i ];
-	} else	/* use creation date */
+	} else {
+		/*
+		 * Fallback - use creation date
+		 */
 		fsid = hsvp->cre_date.tv_sec;
+	}
 
 	brelse(bp);
 
@@ -626,6 +635,7 @@
 		if (hs_remakenode(fsp->hsfs_vol.root_dir.ext_lbn,
 			    (uint_t)0, vfsp, &fsp->hsfs_rootvp)) {
 			error = EINVAL;
+			mutex_exit(&hs_mounttab_lock);
 			goto cleanup;
 		}
 	} else {