Re: NULL pointer dereference at 0000000000000038 IP: [<ffffffff815f514f>] bitmap_load+0x45f/0x610

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, 19 Jun 2015 17:18:45 -0400 Nate Clark <nate@xxxxxxxxxx> wrote:

> Hi,
> 
> I encountered a null pointer in md on kernel 4.0.4 and 4.0.5. I was running
> Fedora so I filed this bug with redhat,
> https://bugzilla.redhat.com/show_bug.cgi?id=1232492.
> 
> It seems pretty easy to encounter.
> 1) Add PROGRAM line in mdadm.conf, which points to a script that just
> sleeps for 5 or 10 seconds
> 2) Create md device (I used raid 1 but I don't think that matters)
> 3) Stop that md device
> 4) Before the monitor program finishes execution assemble that md device.
> 
> On my system this always cause an Oops.

Hi,
 thanks for the report.
I managed to reproduce this, though it didn't seem quite as easy for me as for
you.

Anyway I found the bug and have a fix - see below.
should get into 4.2 soon and into stable releases in due course.

Thanks,
NeilBrown

From: NeilBrown <neilb@xxxxxxx>
Date: Thu, 25 Jun 2015 17:01:40 +1000
Subject: [PATCH] md: clear mddev->private when it has been freed.

If ->private is set when ->run is called, it is assumed to be
a 'config'  prepared as part of 'reshape'.

So it is important when we free that config, that we also clear ->private.
This is not often a problem as the mddev will normally be discarded
shortly after the config us freed.
However if an 'assemble' races with a final close, the assemble can use
the old mddev which has a stale ->private.  This leads to any of
various sorts of crashes.

So clear ->private after calling ->free().

Reported-by: Nate Clark <nate@xxxxxxxxxx>
Cc: stable@xxxxxxxxxxxxxxx (v4.0+)
Fixes: afa0f557cb15 ("md: rename ->stop to ->free")
Signed-off-by: NeilBrown <neilb@xxxxxxxx>

diff --git a/drivers/md/md.c b/drivers/md/md.c
index 5a6681ad9778..4b7b31b6f25c 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -5178,6 +5178,7 @@ int md_run(struct mddev *mddev)
 		mddev_detach(mddev);
 		if (mddev->private)
 			pers->free(mddev, mddev->private);
+		mddev->private = NULL;
 		module_put(pers->owner);
 		bitmap_destroy(mddev);
 		return err;
@@ -5313,6 +5314,7 @@ static void md_clean(struct mddev *mddev)
 	mddev->changed = 0;
 	mddev->degraded = 0;
 	mddev->safemode = 0;
+	mddev->private = NULL;
 	mddev->merge_check_needed = 0;
 	mddev->bitmap_info.offset = 0;
 	mddev->bitmap_info.default_offset = 0;
@@ -5385,6 +5387,7 @@ static void __md_stop(struct mddev *mddev)
 	mddev->pers = NULL;
 	spin_unlock(&mddev->lock);
 	pers->free(mddev, mddev->private);
+	mddev->private = NULL;
 	if (pers->sync_request && mddev->to_remove == NULL)
 		mddev->to_remove = &md_redundancy_group;
 	module_put(pers->owner);

--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux