⬢ DragonFlyBSD Kernel Audit
DF-5063 / fix.diff
← back to finding ↓ download raw
diff -ruN a/sys/dev/raid/vinum/vinumconfig.c b/sys/dev/raid/vinum/vinumconfig.c
--- a/sys/dev/raid/vinum/vinumconfig.c	2026-09-26 18:53:20.555916356 +0000
+++ b/sys/dev/raid/vinum/vinumconfig.c	2026-09-26 18:53:29.411801861 +0000
@@ -760,6 +760,19 @@
 made_vol(struct volume *vol)
 {
     if (vol->vol_dev == NULL && vol->state != volume_unallocated) {
+	/*
+	 * DF-5062: the volume number is encoded in the low VINUM_VOL_WIDTH
+	 * bits of the device minor.  Never create a node for a volume number
+	 * that does not decode back to itself: volume #256 would get minor
+	 * 0x100, which Volno() decodes as volno 0, silently aliasing every
+	 * access onto VOL[0] (cross-volume data corruption).
+	 */
+	if (vol->volno >= (1 << VINUM_VOL_WIDTH)) {
+	    log(LOG_ERR, "vinum: volume %s: volume number %d does not fit in "
+		"the %d-bit device minor; no device node created\n",
+		vol->name, vol->volno, VINUM_VOL_WIDTH);
+	    return;
+	}
 	vol->vol_dev = make_dev(&vinum_ops,
 				VINUMDEV(vol->volno, 0, 0, VINUM_VOLUME_TYPE),
 				UID_ROOT, GID_OPERATOR, 0640,
diff -ruN a/sys/dev/raid/vinum/vinumutil.c b/sys/dev/raid/vinum/vinumutil.c
--- a/sys/dev/raid/vinum/vinumutil.c	2026-09-26 18:53:20.559916305 +0000
+++ b/sys/dev/raid/vinum/vinumutil.c	2026-09-26 18:53:29.431801603 +0000
@@ -258,7 +258,14 @@
 
     case VINUM_PLEX_TYPE:
     case VINUM_SD_TYPE:
-	return VOL[Volno(dev)].plex[(minor(dev) >> VINUM_PLEX_SHIFT) & (MASK(VINUM_PLEX_WIDTH))];
+	{
+	    int volno = Volno(dev);			    /* DF-5063: validate */
+	    int plexord = (minor(dev) >> VINUM_PLEX_SHIFT) & (MASK(VINUM_PLEX_WIDTH));
+
+	    if (volno >= vinum_conf.volumes_allocated)	    /* no such volume */
+		return -1;				    /* never touch VOL[] */
+	    return VOL[volno].plex[plexord];		    /* may be -1: empty slot */
+	}
 
     case VINUM_RAWPLEX_TYPE:
 	return ((minor(dev) & MASK(VINUM_VOL_WIDTH)) >> VINUM_VOL_SHIFT) /* low order 8 bits */
@@ -286,7 +293,14 @@
 	return -1;
 
     case VINUM_SD_TYPE:
-	return PLEX[Plexno(dev)].sdnos[(minor(dev) >> VINUM_SD_SHIFT) & (MASK(VINUM_SD_WIDTH))];
+	{
+	    int plexno = Plexno(dev);			    /* DF-5063: validate */
+	    int sdord = (minor(dev) >> VINUM_SD_SHIFT) & (MASK(VINUM_SD_WIDTH));
+
+	    if ((plexno < 0) || (plexno >= vinum_conf.plexes_allocated))
+		return -1;				    /* never index PLEX[-1] */
+	    return PLEX[plexno].sdnos[sdord];
+	}
 
     case VINUM_RAWSD_TYPE:
 	return ((minor(dev) & MASK(VINUM_VOL_WIDTH)) >> VINUM_VOL_SHIFT) /* low order 8 bits */