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