Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 1805

kernel-2.6.18-238.el5.src.rpm

From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Thu, 7 Oct 2010 08:47:48 -0400
Subject: [md] raid0: fix data corruption on 32-bit w/large storage
Message-id: <20101007084748.GB2435@redhat.com>
Patchwork-id: 28646
O-Subject: [RHEL5 PATCH] md: fix raid0 data corruption
Bugzilla: 573185
RH-Acked-by: Ivan Vecera <ivecera@redhat.com>
RH-Acked-by: Tomas Henzl <thenzl@redhat.com>
RH-Acked-by: Doug Ledford <dledford@redhat.com>

BZ#573185

Description:
User report data corruption on large storage. Problem happens on 32 bit
system with software raid0 configured on top of large (more than 8TB)
block devices.

We have 32-bit variable overflow in raid0_make_request function in line:

rsect = (((chunk << chunksize_bits) + zone->dev_offset)<<1)

If chunk is a 32 bit variable, it can overflow during shift operation by
chunksize_bit, giving as result bad value of rsect.

Upstream:
commit 787f17feb204ed1c6331892fb8124b80dc9fe288
Author: NeilBrown <neilb@suse.de>
Date:   Wed May 23 13:58:09 2007 -0700

    md: avoid overflow in raid0 calculation with large component

Testing:
Tested by creating raid0 on top of two 8TB sparse files. I attached
reproducer to bug report. Not seeing corruption after apply the patch.


diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index cb8c631..fca787e 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -398,7 +398,7 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio)
 	raid0_conf_t *conf = mddev_to_conf(mddev);
 	struct strip_zone *zone;
 	mdk_rdev_t *tmp_dev;
-	unsigned long chunk;
+	sector_t chunk;
 	sector_t block, rsect;
 	const int rw = bio_data_dir(bio);
 
@@ -453,7 +453,6 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio)
 
 		sector_div(x, zone->nb_dev);
 		chunk = x;
-		BUG_ON(x != (sector_t)chunk);
 
 		x = block >> chunksize_bits;
 		tmp_dev = zone->dev[sector_div(x, zone->nb_dev)];