Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 5 Feb 2011 20:23:12 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r218336 - projects/graid/head/sys/geom/raid
Message-ID:  <201102052023.p15KNCLv039238@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Sat Feb  5 20:23:12 2011
New Revision: 218336
URL: http://svn.freebsd.org/changeset/base/218336

Log:
  Validate main metadata fields on read to avoid later surprises.
  
  Skip disks with metadata describing volumes in unsupported migration states
  to not damage data with wrong handling.

Modified:
  projects/graid/head/sys/geom/raid/md_intel.c

Modified: projects/graid/head/sys/geom/raid/md_intel.c
==============================================================================
--- projects/graid/head/sys/geom/raid/md_intel.c	Sat Feb  5 19:13:38 2011	(r218335)
+++ projects/graid/head/sys/geom/raid/md_intel.c	Sat Feb  5 20:23:12 2011	(r218336)
@@ -330,8 +330,10 @@ intel_meta_read(struct g_consumer *cp)
 {
 	struct g_provider *pp;
 	struct intel_raid_conf *meta;
+	struct intel_raid_vol *mvol;
+	struct intel_raid_map *mmap;
 	char *buf;
-	int error, i, left;
+	int error, i, j, k, left, size;
 	uint32_t checksum, *ptr;
 
 	pp = cp->provider;
@@ -352,14 +354,15 @@ intel_meta_read(struct g_consumer *cp)
 		g_free(buf);
 		return (NULL);
 	}
-	if (meta->config_size > 65536) {
-		G_RAID_DEBUG(1, "Intel metadata size looks too big: %d",
+	if (meta->config_size > 65536 ||
+	    meta->config_size < sizeof(struct intel_raid_conf)) {
+		G_RAID_DEBUG(1, "Intel metadata size looks wrong: %d",
 		    meta->config_size);
 		g_free(buf);
 		return (NULL);
 	}
 	meta = malloc(meta->config_size, M_MD_INTEL, M_WAITOK);
-	memcpy(meta, buf, pp->sectorsize);
+	memcpy(meta, buf, min(meta->config_size, pp->sectorsize));
 	g_free(buf);
 
 	/* Read all the rest, if needed. */
@@ -392,6 +395,68 @@ intel_meta_read(struct g_consumer *cp)
 		return (NULL);
 	}
 
+	/* Validate metadata size. */
+	size = sizeof(struct intel_raid_conf) +
+	    sizeof(struct intel_raid_disk) * (meta->total_disks - 1) +
+	    sizeof(struct intel_raid_vol) * meta->total_volumes;
+	if (size > meta->config_size) {
+badsize:
+		G_RAID_DEBUG(1, "Intel metadata size incorrect %d < %d",
+		    meta->config_size, size);
+		free(meta, M_MD_INTEL);
+		return (NULL);
+	}
+	for (i = 0; i < meta->total_volumes; i++) {
+		mvol = intel_get_volume(meta, i);
+		mmap = intel_get_map(mvol, 0);
+		size += 4 * (mmap->total_disks - 1);
+		if (size > meta->config_size)
+			goto badsize;
+		if (mvol->migr_state) {
+			size += sizeof(struct intel_raid_map);
+			if (size > meta->config_size)
+				goto badsize;
+			mmap = intel_get_map(mvol, 1);
+			size += 4 * (mmap->total_disks - 1);
+			if (size > meta->config_size)
+				goto badsize;
+		}
+	}
+
+	/* Validate disk indexes. */
+	for (i = 0; i < meta->total_volumes; i++) {
+		mvol = intel_get_volume(meta, i);
+		for (j = 0; j < (mvol->migr_state ? 2 : 1); j++) {
+			mmap = intel_get_map(mvol, j);
+			for (k = 0; k < mmap->total_disks; k++) {
+				if ((mmap->disk_idx[k] & INTEL_DI_IDX) >
+				    meta->total_disks) {
+					G_RAID_DEBUG(1, "Intel metadata disk"
+					    " index %d too big (>%d)",
+					    mmap->disk_idx[k] & INTEL_DI_IDX,
+					    meta->total_disks);
+					free(meta, M_MD_INTEL);
+					return (NULL);
+				}
+			}
+		}
+	}
+
+	/* Validate migration types. */
+	for (i = 0; i < meta->total_volumes; i++) {
+		mvol = intel_get_volume(meta, i);
+		if (mvol->migr_state &&
+		    mvol->migr_type != INTEL_MT_INIT &&
+		    mvol->migr_type != INTEL_MT_REBUILD &&
+		    mvol->migr_type != INTEL_MT_VERIFY &&
+		    mvol->migr_type != INTEL_MT_REPAIR) {
+			G_RAID_DEBUG(1, "Intel metadata has unsupported"
+			    " migration type %d", mvol->migr_type);
+			free(meta, M_MD_INTEL);
+			return (NULL);
+		}
+	}
+
 	return (meta);
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201102052023.p15KNCLv039238>