aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2005-12-12 05:39:16 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2005-12-12 12:06:04 -0500
commit3795bb0fc52fe2af2749f3ad2185cb9c90871ef8 (patch)
tree764aa053d592b4ce555e2ca91077d7c6fc9eaa16 /drivers/md
parent0de502aa44aae5712a18d471818d6c785e07c92e (diff)
[PATCH] md: fix a use-after-free bug in raid1
Who would submit code with a FIXME like that in it !!!! Signed-off-by: Neil Brown <neilb@suse.de> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/raid1.c5
1 files changed, 3 insertions, 2 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 3066c587b539..229d7b204297 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -320,7 +320,6 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
320 * this branch is our 'one mirror IO has finished' event handler: 320 * this branch is our 'one mirror IO has finished' event handler:
321 */ 321 */
322 r1_bio->bios[mirror] = NULL; 322 r1_bio->bios[mirror] = NULL;
323 bio_put(bio);
324 if (!uptodate) { 323 if (!uptodate) {
325 md_error(r1_bio->mddev, conf->mirrors[mirror].rdev); 324 md_error(r1_bio->mddev, conf->mirrors[mirror].rdev);
326 /* an I/O failed, we can't clear the bitmap */ 325 /* an I/O failed, we can't clear the bitmap */
@@ -377,7 +376,6 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
377 } 376 }
378 if (test_bit(R1BIO_BehindIO, &r1_bio->state)) { 377 if (test_bit(R1BIO_BehindIO, &r1_bio->state)) {
379 /* free extra copy of the data pages */ 378 /* free extra copy of the data pages */
380/* FIXME bio has been freed!!! */
381 int i = bio->bi_vcnt; 379 int i = bio->bi_vcnt;
382 while (i--) 380 while (i--)
383 __free_page(bio->bi_io_vec[i].bv_page); 381 __free_page(bio->bi_io_vec[i].bv_page);
@@ -391,6 +389,9 @@ static int raid1_end_write_request(struct bio *bio, unsigned int bytes_done, int
391 raid_end_bio_io(r1_bio); 389 raid_end_bio_io(r1_bio);
392 } 390 }
393 391
392 if (r1_bio->bios[mirror]==NULL)
393 bio_put(bio);
394
394 rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev); 395 rdev_dec_pending(conf->mirrors[mirror].rdev, conf->mddev);
395 return 0; 396 return 0;
396} 397}