Subject: bin/26637: newfs reads/writes blocks smaller than the sector size
To: None <gnats-bugs@gnats.NetBSD.org>
From: None <cjs@netbsd.org>
List: netbsd-bugs
Date: 08/13/2004 17:17:45
>Number:         26637
>Category:       bin
>Synopsis:       newfs reads/writes blocks smaller than the sector size
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Aug 13 08:18:00 UTC 2004
>Closed-Date:
>Last-Modified:
>Originator:     Curt Sampson
>Release:        NetBSD 2.0_BETA Mon Jul 12 01:40:25 UTC 2004
>Organization:
>Environment:
System: NetBSD dev1.tabemo.com 2.0_BETA NetBSD 2.0_BETA (GENERIC) #0: Mon Jul 12 01:40:25 UTC 2004 autobuild@tgm.netbsd.org:/autobuild/netbsd-2-0/i386/OBJ/autobuild/netbsd-2-0/src/sys/arch/i386/compile/GENERIC i386
Architecture: i386
Machine: i386
>Description:

    newfs, when trying to create a new filesystem, at one point attempts
    to read and possibly write a buffer that is potentially smaller than
    the sector size of the device.

>How-To-Repeat:

    Attempt to newfs a DVD-RAM or anything else with a 2048 byte or larger
    sector size.

>Fix:

Here's a patch against 2.0-beta:

Index: mkfs.c
===================================================================
RCS file: /cvsroot/src/sbin/newfs/mkfs.c,v
retrieving revision 1.87.2.1
diff -u -r1.87.2.1 mkfs.c
--- mkfs.c	27 Apr 2004 17:26:24 -0000	1.87.2.1
+++ mkfs.c	13 Aug 2004 08:17:20 -0000
@@ -171,6 +171,9 @@
 	long long sizepb;
 	int nprintcols, printcolwidth;
 
+	struct appleufslabel *appleufs;
+	int appleufs_bufsize;
+
 #ifndef STANDALONE
 	gettimeofday(&tv, NULL);
 #endif
@@ -605,23 +608,34 @@
 			zap_old_sblock(roundup(sblkoff, sz));
 	}
 
+	if (sectorsize > APPLEUFS_LABEL_SIZE)
+		appleufs_bufsize = sectorsize;
+	else
+		appleufs_bufsize = APPLEUFS_LABEL_SIZE;
+	appleufs = malloc(appleufs_bufsize);
+	if (appleufs == NULL) {
+		printf("Out of memory.\n");
+		exit(1);
+	}
+
 	if (isappleufs) {
-		struct appleufslabel appleufs;
-		ffs_appleufs_set(&appleufs, appleufs_volname, tv.tv_sec, 0);
-		wtfs(APPLEUFS_LABEL_OFFSET/sectorsize, APPLEUFS_LABEL_SIZE, 
-		    &appleufs);
+		ffs_appleufs_set(appleufs, appleufs_volname, tv.tv_sec, 0);
+		wtfs(APPLEUFS_LABEL_OFFSET/sectorsize, appleufs_bufsize, 
+		    appleufs);
+		free(appleufs);
 	} else {
-		struct appleufslabel appleufs;
 		/* Look for and zap any existing valid apple ufs labels */
-		rdfs(APPLEUFS_LABEL_OFFSET/sectorsize, APPLEUFS_LABEL_SIZE, 
-		    &appleufs);
-		if (ffs_appleufs_validate(fsys, &appleufs, NULL) == 0) {
-			memset(&appleufs, 0, sizeof(appleufs));
-			wtfs(APPLEUFS_LABEL_OFFSET/sectorsize, APPLEUFS_LABEL_SIZE, 
-			    &appleufs);
+		rdfs(APPLEUFS_LABEL_OFFSET/sectorsize, appleufs_bufsize, 
+		    appleufs);
+		if (ffs_appleufs_validate(fsys, appleufs, NULL) == 0) {
+			memset(appleufs, 0, sizeof(struct appleufslabel));
+			wtfs(APPLEUFS_LABEL_OFFSET/sectorsize, appleufs_bufsize, 
+			    appleufs);
 		}
 	}
 
+	free(appleufs);
+
 	/*
 	 * Make a copy of the superblock into the buffer that we will be
 	 * writing out in each cylinder group.
>Release-Note:
>Audit-Trail:
>Unformatted: