Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0eb25bb0 authored by NeilBrown's avatar NeilBrown
Browse files

md/raid10: remove use-after-free bug.



We always need to be careful when calling generic_make_request, as it
can start a chain of events which might free something that we are
using.

Here is one place I wasn't careful enough.  If the wbio2 is not in
use, then it might get freed at the first generic_make_request call.
So perform all necessary tests first.

This bug was introduced in 3.3-rc3 (24afd80d) and can cause an
oops, so fix is suitable for any -stable since then.

Cc: stable@vger.kernel.org (3.3+)
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
parent 30bc9b53
Loading
Loading
Loading
Loading
+7 −1
Original line number Original line Diff line number Diff line
@@ -2290,12 +2290,18 @@ static void recovery_request_write(struct mddev *mddev, struct r10bio *r10_bio)
	d = r10_bio->devs[1].devnum;
	d = r10_bio->devs[1].devnum;
	wbio = r10_bio->devs[1].bio;
	wbio = r10_bio->devs[1].bio;
	wbio2 = r10_bio->devs[1].repl_bio;
	wbio2 = r10_bio->devs[1].repl_bio;
	/* Need to test wbio2->bi_end_io before we call
	 * generic_make_request as if the former is NULL,
	 * the latter is free to free wbio2.
	 */
	if (wbio2 && !wbio2->bi_end_io)
		wbio2 = NULL;
	if (wbio->bi_end_io) {
	if (wbio->bi_end_io) {
		atomic_inc(&conf->mirrors[d].rdev->nr_pending);
		atomic_inc(&conf->mirrors[d].rdev->nr_pending);
		md_sync_acct(conf->mirrors[d].rdev->bdev, bio_sectors(wbio));
		md_sync_acct(conf->mirrors[d].rdev->bdev, bio_sectors(wbio));
		generic_make_request(wbio);
		generic_make_request(wbio);
	}
	}
	if (wbio2 && wbio2->bi_end_io) {
	if (wbio2) {
		atomic_inc(&conf->mirrors[d].replacement->nr_pending);
		atomic_inc(&conf->mirrors[d].replacement->nr_pending);
		md_sync_acct(conf->mirrors[d].replacement->bdev,
		md_sync_acct(conf->mirrors[d].replacement->bdev,
			     bio_sectors(wbio2));
			     bio_sectors(wbio2));