[dm-devel] [PATCH] dm-ioctl.c: Don't overrun ioctl buffer

thornber at redhat.com thornber at redhat.com
Wed Apr 7 12:33:42 UTC 2004


2.6 patches attached.

- Joe
-------------- next part --------------
mirror: Use an EMIT macro in the status fn.
--- diff/drivers/md/dm-raid1.c	2004-04-07 11:34:56.983607984 +0100
+++ source/drivers/md/dm-raid1.c	2004-04-07 13:12:32.330459960 +0100
@@ -1189,32 +1189,32 @@ static int mirror_status(struct dm_targe
 	unsigned int m, sz = 0;
 	struct mirror_set *ms = (struct mirror_set *) ti->private;
 
+#define EMIT(x...) sz += ((sz >= maxlen) ? \
+			  0 : scnprintf(result + sz, maxlen - sz, x))
+
 	switch (type) {
 	case STATUSTYPE_INFO:
-		sz += scnprintf(result + sz, maxlen - sz, "%d ", ms->nr_mirrors);
+		EMIT("%d ", ms->nr_mirrors);
 
 		for (m = 0; m < ms->nr_mirrors; m++) {
 			format_dev_t(buffer, ms->mirror[m].dev->bdev->bd_dev);
-			sz += scnprintf(result + sz, maxlen - sz, "%s ", buffer);
+			EMIT("%s ", buffer);
 		}
 
-		sz += scnprintf(result + sz, maxlen - sz,
-			       SECTOR_FORMAT "/" SECTOR_FORMAT,
-			       ms->rh.log->type->get_sync_count(ms->rh.log),
-			       ms->nr_regions);
+		EMIT(SECTOR_FORMAT "/" SECTOR_FORMAT,
+		     ms->rh.log->type->get_sync_count(ms->rh.log),
+		     ms->nr_regions);
 		break;
 
 	case STATUSTYPE_TABLE:
-		sz += scnprintf(result + sz, maxlen - sz,
-			       "%s 1 " SECTOR_FORMAT " %d ",
-			       ms->rh.log->type->name, ms->rh.region_size,
-			       ms->nr_mirrors);
+		EMIT("%s 1 " SECTOR_FORMAT " %d ",
+		     ms->rh.log->type->name, ms->rh.region_size,
+		     ms->nr_mirrors);
 
 		for (m = 0; m < ms->nr_mirrors; m++) {
 			format_dev_t(buffer, ms->mirror[m].dev->bdev->bd_dev);
-			sz += scnprintf(result + sz, maxlen - sz,
-				       "%s " SECTOR_FORMAT " ",
-				       buffer, ms->mirror[m].offset);
+			EMIT("%s " SECTOR_FORMAT " ",
+			     buffer, ms->mirror[m].offset);
 		}
 	}
 
-------------- next part --------------
Striped: Use an EMIT macro in the status function.
--- diff/drivers/md/dm-stripe.c	2004-04-05 12:57:08.000000000 +0100
+++ source/drivers/md/dm-stripe.c	2004-04-07 13:18:25.805723552 +0100
@@ -187,24 +187,24 @@ static int stripe_status(struct dm_targe
 			 status_type_t type, char *result, unsigned int maxlen)
 {
 	struct stripe_c *sc = (struct stripe_c *) ti->private;
-	int offset;
+	unsigned int sz = 0;
 	unsigned int i;
 	char buffer[32];
 
+#define EMIT(x...) sz += ((sz >= maxlen) ? \
+			  0 : scnprintf(result + sz, maxlen - sz, x))
+
 	switch (type) {
 	case STATUSTYPE_INFO:
 		result[0] = '\0';
 		break;
 
 	case STATUSTYPE_TABLE:
-		offset = scnprintf(result, maxlen, "%d " SECTOR_FORMAT,
-				  sc->stripes, sc->chunk_mask + 1);
+		EMIT("%d " SECTOR_FORMAT, sc->stripes, sc->chunk_mask + 1);
 		for (i = 0; i < sc->stripes; i++) {
 			format_dev_t(buffer, sc->stripe[i].dev->bdev->bd_dev);
-			offset +=
-			    scnprintf(result + offset, maxlen - offset,
-				     " %s " SECTOR_FORMAT, buffer,
-				     sc->stripe[i].physical_start);
+			EMIT(" %s " SECTOR_FORMAT, buffer,
+			     sc->stripe[i].physical_start);
 		}
 		break;
 	}
-------------- next part --------------
dm-ioctl: change so that the target status function is never
called with a buffer size limit of zero.  [Alasdair Kergon]
--- diff/drivers/md/dm-ioctl.c	2004-04-07 11:32:58.068685800 +0100
+++ source/drivers/md/dm-ioctl.c	2004-04-07 13:28:04.607732272 +0100
@@ -800,7 +800,7 @@ static void retrieve_status(struct dm_ta
 		struct dm_target *ti = dm_table_get_target(table, i);
 
 		remaining = len - (outptr - outbuf);
-		if (remaining < sizeof(struct dm_target_spec)) {
+		if (remaining <= sizeof(struct dm_target_spec)) {
 			param->flags |= DM_BUFFER_FULL_FLAG;
 			break;
 		}


More information about the dm-devel mailing list