From: Dan Williams Date: Sat, 1 Aug 2009 00:11:41 +0000 (-0700) Subject: fix examine_brief segfault X-Git-Tag: mdadm-3.0.1~6^2~7 X-Git-Url: http://git.ipfire.org/?p=thirdparty%2Fmdadm.git;a=commitdiff_plain;h=37424f132cb3874fe51021b1b5e04445a3ba1bdb fix examine_brief segfault When performing an "-Ebs -e " we segfault because the superblock has been freed too early. We also leak memory for 'ddf' and 'imsm' because, unlike super[01], we do not implicitly free when ->load_super is called on an already loaded supertype. So, fix up imsm and ddf to match type 0 and 1 ->load_super() semantics, and update Examine to not free the superblock until all usages have been exhausted. Signed-off-by: Dan Williams --- diff --git a/Examine.c b/Examine.c index f0e98f97..3d0ea8a5 100644 --- a/Examine.c +++ b/Examine.c @@ -114,10 +114,8 @@ int Examine(mddev_dev_t devlist, int brief, int export, int scan, ap->st = st; arrays = ap; st->ss->getinfo_super(st, &ap->info); - } else { + } else st->ss->getinfo_super(st, &ap->info); - st->ss->free_super(st); - } if (!(ap->info.disk.state & (1<spares++; d = dl_strdup(devlist->devname); diff --git a/super-ddf.c b/super-ddf.c index 517a5864..8153924e 100644 --- a/super-ddf.c +++ b/super-ddf.c @@ -762,6 +762,9 @@ static int load_ddf_local(int fd, struct ddf_super *super, static int load_super_ddf_all(struct supertype *st, int fd, void **sbp, char *devname, int keep_fd); #endif + +static void free_super_ddf(struct supertype *st); + static int load_super_ddf(struct supertype *st, int fd, char *devname) { @@ -798,6 +801,8 @@ static int load_super_ddf(struct supertype *st, int fd, return 1; } + free_super_ddf(st); + if (posix_memalign((void**)&super, 512, sizeof(*super))!= 0) { fprintf(stderr, Name ": malloc of %zu failed.\n", sizeof(*super)); diff --git a/super-intel.c b/super-intel.c index 24827d0b..7b04a79e 100644 --- a/super-intel.c +++ b/super-intel.c @@ -2196,6 +2196,8 @@ static int load_super_imsm(struct supertype *st, int fd, char *devname) return 0; #endif + free_super_imsm(st); + super = alloc_super(0); if (!super) { fprintf(stderr,