diff options
author | Pawel Baldysiak <pawel.baldysiak@intel.com> | 2022-09-01 11:20:31 +0200 |
---|---|---|
committer | Jes Sorensen <jsorensen@fb.com> | 2022-09-08 18:56:37 +0200 |
commit | 55c10e4de13abe3e6934895e1fff7d2d20d0b2c2 (patch) | |
tree | 5f50e6eb51608caf15ad988bc5c1b85052c95ff7 /Monitor.c | |
parent | Manage: Block unsafe member failing (diff) | |
download | mdadm-55c10e4de13abe3e6934895e1fff7d2d20d0b2c2.tar.xz mdadm-55c10e4de13abe3e6934895e1fff7d2d20d0b2c2.zip |
Monitor: Fix statelist memory leaks
Free statelist in error path in Monitor initialization.
Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
Diffstat (limited to '')
-rw-r--r-- | Monitor.c | 40 |
1 files changed, 31 insertions, 9 deletions
@@ -74,6 +74,7 @@ static int add_new_arrays(struct mdstat_ent *mdstat, struct state **statelist, int test, struct alert_info *info); static void try_spare_migration(struct state *statelist, struct alert_info *info); static void link_containers_with_subarrays(struct state *list); +static void free_statelist(struct state *statelist); #ifndef NO_LIBUDEV static int check_udev_activity(void); #endif @@ -128,7 +129,6 @@ int Monitor(struct mddev_dev *devlist, */ struct state *statelist = NULL; - struct state *st2; int finished = 0; struct mdstat_ent *mdstat = NULL; char *mailfrom; @@ -185,12 +185,14 @@ int Monitor(struct mddev_dev *devlist, continue; if (strcasecmp(mdlist->devname, "<ignore>") == 0) continue; + if (!is_mddev(mdlist->devname)) { + free_statelist(statelist); + return 1; + } st = xcalloc(1, sizeof *st); snprintf(st->devname, MD_NAME_MAX + sizeof("/dev/md/"), "/dev/md/%s", basename(mdlist->devname)); - if (!is_mddev(mdlist->devname)) - return 1; st->next = statelist; st->devnm[0] = 0; st->percent = RESYNC_UNKNOWN; @@ -206,8 +208,10 @@ int Monitor(struct mddev_dev *devlist, for (dv = devlist; dv; dv = dv->next) { struct state *st; - if (!is_mddev(dv->devname)) + if (!is_mddev(dv->devname)) { + free_statelist(statelist); return 1; + } st = xcalloc(1, sizeof *st); mdlist = conf_get_ident(dv->devname); @@ -294,16 +298,16 @@ int Monitor(struct mddev_dev *devlist, for (stp = &statelist; (st = *stp) != NULL; ) { if (st->from_auto && st->err > 5) { *stp = st->next; - free(st->spare_group); + if (st->spare_group) + free(st->spare_group); + free(st); } else stp = &st->next; } } - for (st2 = statelist; st2; st2 = statelist) { - statelist = st2->next; - free(st2); - } + + free_statelist(statelist); if (pidfile) unlink(pidfile); @@ -1056,6 +1060,24 @@ static void link_containers_with_subarrays(struct state *list) } } +/** + * free_statelist() - Frees statelist. + * @statelist: statelist to free + */ +static void free_statelist(struct state *statelist) +{ + struct state *tmp = NULL; + + while (statelist) { + if (statelist->spare_group) + free(statelist->spare_group); + + tmp = statelist; + statelist = statelist->next; + free(tmp); + } +} + #ifndef NO_LIBUDEV /* function: check_udev_activity * Description: Function waits for udev to finish |