From: NeilBrown <nfbrown@suse.com>
Git-commit: e0ee778528bbaad28a5c69d2e219269a3a096607
Subject: md/raid10: fix problem with on-stack allocation of r10bio structure.
Patch-mainline: v3.6-rc3
References: -

A 'struct r10bio' has an array of per-copy information at the end.
This array is declared with size [0] and r10bio_pool_alloc allocates
enough extra space to store the per-copy information depending on the
number of copies needed.

So declaring a 'struct r10bio on the stack isn't going to work.  It
won't allocate enough space, and memory corruption will ensue.

So in the two places where this is done, declare a sufficiently large
structure and use that instead.

The two call-sites of this bug were introduced in 3.4 and 3.5
so this is suitable for both those kernels.  The patch will have to
be modified for 3.4 as it only has one bug.

Cc: stable@vger.kernel.org
Reported-by: Ivan Vasilyev <ivan.vasilyev@gmail.com>
Tested-by: Ivan Vasilyev <ivan.vasilyev@gmail.com>
Signed-off-by: NeilBrown <neilb@suse.de>

---
 drivers/md/raid10.c |   28 ++++++++++++++++++----------
 drivers/md/raid10.h |    2 +-
 2 files changed, 19 insertions(+), 11 deletions(-)

--- linux-3.0-SLE11-SP3.orig/drivers/md/raid10.c
+++ linux-3.0-SLE11-SP3/drivers/md/raid10.c
@@ -558,7 +558,11 @@ static int raid10_mergeable_bvec(struct
 		max = biovec->bv_len;
 
 	if (mddev->merge_check_needed) {
-		struct r10bio_s r10_bio;
+		struct {
+			struct r10bio_s r10_bio;
+			struct r10dev devs[conf->copies];
+		} on_stack;
+		struct r10bio_s *r10_bio = &on_stack.r10_bio;
 		int s;
 		if (conf->reshape_progress != MaxSector) {
 			/* Cannot give any guidance during reshape */
@@ -566,18 +570,18 @@ static int raid10_mergeable_bvec(struct
 				return biovec->bv_len;
 			return 0;
 		}
-		r10_bio.sector = sector;
-		raid10_find_phys(conf, &r10_bio);
+		r10_bio->sector = sector;
+		raid10_find_phys(conf, r10_bio);
 		rcu_read_lock();
 		for (s = 0; s < conf->copies; s++) {
-			int disk = r10_bio.devs[s].devnum;
+			int disk = r10_bio->devs[s].devnum;
 			mdk_rdev_t *rdev = rcu_dereference(
 				conf->mirrors[disk].rdev);
 			if (rdev && !test_bit(Faulty, &rdev->flags)) {
 				struct request_queue *q =
 					bdev_get_queue(rdev->bdev);
 				if (q->merge_bvec_fn) {
-					bvm->bi_sector = r10_bio.devs[s].addr
+					bvm->bi_sector = r10_bio->devs[s].addr
 						+ rdev->data_offset;
 					bvm->bi_bdev = rdev->bdev;
 					max = min(max, q->merge_bvec_fn(
@@ -3611,14 +3615,18 @@ static int handle_reshape_read_error(mdd
 {
 	/* Use sync reads to get the blocks from somewhere else */
 	int sectors = r10_bio->sectors;
-	struct r10bio_s r10b;
 	conf_t *conf = mddev->private;
+	struct {
+		struct r10bio_s r10_bio;
+		struct r10dev devs[conf->copies];
+	} on_stack;
+	struct r10bio_s *r10b = &on_stack.r10_bio;
 	int slot = 0;
 	int idx = 0;
 	struct bio_vec *bvec = r10_bio->master_bio->bi_io_vec;
 
-	r10b.sector = r10_bio->sector;
-	__raid10_find_phys(&conf->prev, &r10b);
+	r10b->sector = r10_bio->sector;
+	__raid10_find_phys(&conf->prev, r10b);
 
 	while (sectors) {
 		int s = sectors;
@@ -3629,7 +3637,7 @@ static int handle_reshape_read_error(mdd
 			s = PAGE_SIZE >> 9;
 
 		while (!success) {
-			int d = r10b.devs[slot].devnum;
+			int d = r10b->devs[slot].devnum;
 			mdk_rdev_t *rdev = conf->mirrors[d].rdev;
 			sector_t addr;
 			if (rdev == NULL ||
@@ -3637,7 +3645,7 @@ static int handle_reshape_read_error(mdd
 			    !test_bit(In_sync, &rdev->flags))
 				goto failed;
 
-			addr = r10b.devs[slot].addr + idx * PAGE_SIZE;
+			addr = r10b->devs[slot].addr + idx * PAGE_SIZE;
 			success = sync_page_io(rdev,
 					       addr,
 					       s << 9,
--- linux-3.0-SLE11-SP3.orig/drivers/md/raid10.h
+++ linux-3.0-SLE11-SP3/drivers/md/raid10.h
@@ -107,7 +107,7 @@ struct r10bio_s {
 	 * When reconstructing, we use 2 bios, one for read, one for write.
 	 * We choose the number when they are allocated.
 	 */
-	struct {
+	struct r10dev {
 		struct bio		*bio;
 		sector_t addr;
 		int devnum;
