changeset 1025:1aef26bcfa0e

6300064 hsfs_spec.h has developed a southern drawl. 6338131 IDE_SUA_LEN() macro can cause integer underflow 6339513 strlcat() isn't always appropriate ... 6343199 hsfs mount error exit part still doesn't clean up correctly
author frankho
date Thu, 01 Dec 2005 02:59:10 -0800
parents 25c63934cfc4
children 85026e519b4d
files usr/src/uts/common/fs/hsfs/hsfs_rrip.c usr/src/uts/common/fs/hsfs/hsfs_susp_subr.c usr/src/uts/common/fs/hsfs/hsfs_vfsops.c usr/src/uts/common/sys/fs/hsfs_isospec.h usr/src/uts/common/sys/fs/hsfs_spec.h
diffstat 5 files changed, 65 insertions(+), 46 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/fs/hsfs/hsfs_rrip.c	Wed Nov 30 14:11:33 2005 -0800
+++ b/usr/src/uts/common/fs/hsfs/hsfs_rrip.c	Thu Dec 01 02:59:10 2005 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -51,7 +50,6 @@
 #include <sys/mode.h>
 #include <sys/mkdev.h>
 #include <sys/ddi.h>
-#include <sys/sunddi.h>
 
 #include <vm/page.h>
 
@@ -240,22 +238,29 @@
 	}
 
 	/*
-	 * Since SUA_string isn't NULL terminated, we use strlcat()
-	 * to add the trailing NULL byte. Defensive programming, don't
-	 * ever overwrite beyond the end of the destination buffer,
-	 * and neither attempt to read beyond the end of SUA_string.
-	 * We assume the caller properly validates SUA_string_len as
-	 * we have no way of doing so.
-	 * Note for corrupted filesystems, SUA_string may contain
-	 * NULL bytes. If that happens, the destination string length
-	 * returned will be larger than the "actual" length, since
-	 * strlcat() terminates when encountering the NULL byte.
-	 * This causes no harm (apart from filenames not being reported
-	 * 'correctly', but then what is correct on a corrupted fs ?)
-	 * so we don't bother assigning strlen(dst) to *dst_lenp.
+	 * strlcat() has two nice properties:
+	 * - the size of the output buffer includes the trailing '\0'
+	 * - we pass "total size" not "remaining size"
+	 * It'd be the ideal candidate for this codeblock - make it:
+	 *
+	 *	strlcat(dst, SUA_string,
+	 *	    MIN(dstsize, strlen(dst) + SUA_string_len + 1));
+	 *
+	 * Unfortunately, strlcat() cannot deal with input strings
+	 * that are not NULL-terminated - like SUA_string can be in
+	 * our case here. So we can't use it :(
+	 * We therefore have to emulate its behaviour using strncat(),
+	 * which will never access more bytes from the input string
+	 * than specified. Since strncat() doesn't necessarily NULL-
+	 * terminate the result, make sure we've got space for the
+	 * Nullbyte at the end.
 	 */
-	*dst_lenp = MIN(dst_size, strlen((char *)dst) + SUA_string_len + 1);
-	(void) strlcat((char *)dst, (char *)SUA_string, (*dst_lenp)--);
+	dst_size--;	/* trailing '\0' */
+
+	(void) strncat((char *)dst, (char *)SUA_string,
+	    MIN(dst_size - strlen((char *)dst), SUA_string_len));
+	dst[dst_size] = '\0';
+	*dst_lenp = strlen((char *)dst);
 
 	if (IS_NAME_BIT_SET(rrip_flags, RRIP_NAME_CONTINUE))
 		SET_NAME_BIT(*(name_flags_p), RRIP_NAME_CONTINUE);
--- a/usr/src/uts/common/fs/hsfs/hsfs_susp_subr.c	Wed Nov 30 14:11:33 2005 -0800
+++ b/usr/src/uts/common/fs/hsfs/hsfs_susp_subr.c	Thu Dec 01 02:59:10 2005 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -66,7 +65,7 @@
 /* static declarations */
 static void free_cont_area(uchar_t *);
 static int get_cont_area(struct hsfs *, uchar_t **, cont_info_t *);
-static int parse_signatures(sig_args_t *, uint_t, uchar_t *, int);
+static int parse_signatures(sig_args_t *, int, uchar_t *, int);
 
 /*
  * parse_sua()
@@ -106,6 +105,14 @@
 		return (0);
 
 	/*
+	 * Underflow on the length field means there's a mismatch
+	 * between sizes of SUA and ISO directory entry. This entry
+	 * is corrupted, return an appropriate error.
+	 */
+	if (SUA_len < 0)
+		return (SUA_EINVAL);
+
+	/*
 	 * Make sure that the continuation lenth is zero, as that is
 	 * the way to tell if we must grab another continuation area.
 	 */
@@ -197,7 +204,7 @@
 static int
 parse_signatures(
 	sig_args_t	*sig_args_p,
-	uint_t		SUA_len,
+	int		SUA_len,
 	uchar_t		*search_sig,	/* possible signature to search for */
 	int		search_num)	/* n^th occurance of search_sig to */
 					/*   search for */
@@ -206,13 +213,16 @@
 	extension_name_t	*extnp;
 	ext_signature_t		*ext_sigp;
 	int			impl_bit_num = 0;
-	uint_t			SUA_rem = SUA_len; /* SUA length */
+	int			SUA_rem = SUA_len; /* SUA length */
 					/* remaining to be parsed */
 
 	/* This should never happen ... just so we don't panic, literally */
 	if (sig_string == (uchar_t *)NULL)
 		return (SUA_NULL_POINTER);
 
+	if (SUA_len < 0)
+		return (SUA_EINVAL);
+
 	/*
 	 * Until the end of SUA, search for the signatures
 	 * (check for end of SUA (2 consecutive NULL bytes)) or the
@@ -249,6 +259,8 @@
 					    SUF_SIG_LEN) == 0) {
 
 					SUA_rem -= SUF_LEN(sig_string);
+					if (SUA_rem < 0)
+						return (END_OF_SUA);
 
 					/*
 					 * The SUA_len parameter specifies the
@@ -386,10 +398,13 @@
 	 * Then we run through the hs_parsedir() function to catch all
 	 * the other possibilities of SUSP fields and continuations.
 	 *
-	 * If there is not SUA area, just return, and assume ISO.
+	 * If there is no SUA area, just return, and assume ISO.
+	 *
+	 * If the SUA area length is invalid (negative, due to a mismatch
+	 * between dirent size and SUA size), return and hope for the best.
 	 */
 
-	if (IDE_SUA_LEN(root_ptr) == 0)
+	if (IDE_SUA_LEN(root_ptr) <= 0)
 		goto end;
 
 	if (strncmp(SUSP_SP, (char *)IDE_sys_use_area(root_ptr),
--- a/usr/src/uts/common/fs/hsfs/hsfs_vfsops.c	Wed Nov 30 14:11:33 2005 -0800
+++ b/usr/src/uts/common/fs/hsfs/hsfs_vfsops.c	Thu Dec 01 02:59:10 2005 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -572,12 +571,10 @@
 	 * Look for a Standard File Structure Volume Descriptor,
 	 * of which there must be at least one.
 	 * If found, check for volume size consistency.
-	 *
-	 * XXX - va_size may someday not be large enough to do this correctly.
 	 */
-	error = hs_findhsvol(fsp, devvp, &fsp->hsfs_vol);
-	if (error == EINVAL) /* not in hs format, try iso 9660 format */
-		error = hs_findisovol(fsp, devvp, &fsp->hsfs_vol);
+	error = hs_findisovol(fsp, devvp, &fsp->hsfs_vol);
+	if (error == EINVAL) /* no iso 9660 - try high sierra ... */
+		error = hs_findhsvol(fsp, devvp, &fsp->hsfs_vol);
 
 	if (error)
 		goto cleanup;
@@ -635,6 +632,10 @@
 		if (hs_remakenode(fsp->hsfs_vol.root_dir.ext_lbn,
 			    (uint_t)0, vfsp, &fsp->hsfs_rootvp)) {
 			error = EINVAL;
+			hs_mounttab = hs_mounttab->hsfs_next;
+			mutex_destroy(&fsp->hsfs_free_lock);
+			rw_destroy(&fsp->hsfs_hash_lock);
+			kmem_free(fsp->hsfs_fsmnt, strlen(path) + 1);
 			mutex_exit(&hs_mounttab_lock);
 			goto cleanup;
 		}
--- a/usr/src/uts/common/sys/fs/hsfs_isospec.h	Wed Nov 30 14:11:33 2005 -0800
+++ b/usr/src/uts/common/sys/fs/hsfs_isospec.h	Thu Dec 01 02:59:10 2005 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,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.
  */
 
@@ -218,8 +217,8 @@
 #define	IDE_NAME_LEN(x)		*(IDE_name_len(x))
 #define	IDE_NAME(x)		IDE_name(x)
 #define	IDE_PAD_LEN(x)		((IDE_NAME_LEN(x) % 2) ? 0 : 1)
-#define	IDE_SUA_LEN(x)		(IDE_DIR_LEN(x) - IDE_FDESIZE - \
-					IDE_NAME_LEN(x) - IDE_PAD_LEN(x))
+#define	IDE_SUA_LEN(x)		((int)(IDE_DIR_LEN(x)) - (int)(IDE_FDESIZE) - \
+				(int)(IDE_NAME_LEN(x)) - (int)(IDE_PAD_LEN(x)))
 
 /* mask bits for IDE_FLAGS */
 #define	IDE_EXISTENCE		0x01	/* zero if file exists */
--- a/usr/src/uts/common/sys/fs/hsfs_spec.h	Wed Nov 30 14:11:33 2005 -0800
+++ b/usr/src/uts/common/sys/fs/hsfs_spec.h	Thu Dec 01 02:59:10 2005 -0800
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,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.
  */
 
@@ -220,7 +219,7 @@
 /* root record */
 #define	HDE_ROOT_DIR_REC_SIZE	34	/* size of root directory record */
 #define	HDE_FDESIZE		33	/* fixed size for hsfs directory area */
-#define	HDE_FUSIZE		12	/* fixed size for unix areaa */
+#define	HDE_FUSIZE		12	/* fixed size for unix area */
 					/* max size of a name */
 #define	HDE_MAX_NAME_LEN	(255 - HDE_FDESIZE - HDE_FUSIZE)