Subject: Disklabel's bug ? (or feature ?)
To: None <tech-userlevel@netbsd.org>
From: Arnaud Lacombe <al@sigfpe.info>
List: tech-userlevel
Date: 06/12/2006 01:33:10
--SLDf9lqlvOQaIe6s
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi,

I had a strange behaviour with disklabel tonight: I wanted to rework the
geometry of a disk, but it was ever and ever returning the same old
label (from an other old disk), and so, even when the disk was not connected.
It finally turned out that I had a file called `rsd0' in /dev which was
containing the first 100 sectors of the old disk, and disklabel was
using this file.

The strange behaviour is (I guess) that disklabel didn't check that the
filemame is a valid device name (ie. like sd0[a-z]). The attached patch is a
sample of test which can be done[1] (the '22' corresponds to
MAXPARTITIONS). Furthermore, shouldn't opendisk() be sure that what it
opens in /dev is really a device file ?

regards,

Arnaud

[1]: not tested or compiled

--SLDf9lqlvOQaIe6s
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="opendisk.c.diff"

--- opendisk.c.orig	Mon Jun 12 00:58:47 2006
+++ opendisk.c	Mon Jun 12 01:05:00 2006
@@ -54,7 +54,7 @@
 int
 opendisk(const char *path, int flags, char *buf, size_t buflen, int iscooked)
 {
-	int f, rawpart;
+	int f, rawpart, len;
 
 	if (buf == NULL) {
 		errno = EFAULT;
@@ -83,10 +83,15 @@
 	if (strchr(path, '/') != NULL)
 		return (-1);
 
-	snprintf(buf, buflen, "%s%s%s", _PATH_DEV, iscooked ? "" : "r", path);
-	f = open(buf, flags);
-	if (f != -1 || errno != ENOENT)
-		return (f);
+	len = strlen(path);
+	if(path[len - 1] > 'a' || path[len - 1] < ('a' + 22)) {
+		snprintf(buf, buflen, "%s%s%s", _PATH_DEV, iscooked ? "" : "r", path);
+		f = open(buf, flags);
+		if (f != -1 || errno != ENOENT)
+			return (f);
+	} else {
+		return -1;
+	}
 
 	snprintf(buf, buflen, "%s%s%s%c", _PATH_DEV, iscooked ? "" : "r", path,
 	    'a' + rawpart);

--SLDf9lqlvOQaIe6s--