[mdadm PATCH 2/11] Enable OLCE for external IMSM metadata

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

 



>From a5fc015d5cdbe58c448ff52d3c244e6a77b1d46e Mon Sep 17 00:00:00 2001
From: Adam Kwolek <adam.kwolek@xxxxxxxxx>
Date: Thu, 18 Feb 2010 11:05:26 +0100
Subject: [PATCH] OLCE: Before OLCE code cleanup and add checks

Changes to be committed:
        modified:   Assemble.c
        modified:   Create.c
        modified:   Detail.c
        modified:   Grow.c
        modified:   Incremental.c
        modified:   Manage.c
        modified:   Monitor.c
        modified:   config.c
        modified:   dlink.c
        modified:   managemon.c
        modified:   mapfile.c
        modified:   mdmon.c
        modified:   mdopen.c
        modified:   mdstat.c
        modified:   monitor.c
        modified:   msg.c
        modified:   platform-intel.c
        modified:   restripe.c
        modified:   super-intel.c
        modified:   sysfs.c
        modified:   util.c

This patch combines changes that are not directly
related to OLCE and can be categorized as improvement.
Summary:
 - Add checks on functions entry
 - set released pointers to NULL
 - Fixed some memory leaks
 - Fixed some issues found by Klocwork

Signed-off-by: Adam Kwolek <adam.kwolek@xxxxxxxxx>
---
 Assemble.c       |   14 ++-
 Create.c         |   10 +-
 Detail.c         |   11 +-
 Grow.c           |   46 ++++++-
 Incremental.c    |   28 +++-
 Manage.c         |   76 +++++++-----
 Monitor.c        |   23 +++-
 config.c         |   49 +++++---
 dlink.c          |   17 ++-
 managemon.c      |  131 ++++++++++++--------
 mapfile.c        |   23 +++-
 mdmon.c          |    7 +-
 mdopen.c         |    4 +-
 mdstat.c         |   24 +++-
 monitor.c        |    4 +
 msg.c            |   10 ++-
 platform-intel.c |    9 +-
 restripe.c       |   12 ++-
 super-intel.c    |  372 +++++++++++++++++++++++++++++++++++++-----------------
 sysfs.c          |   60 ++++++----
 util.c           |  155 ++++++++++++++---------
 21 files changed, 729 insertions(+), 356 deletions(-)

diff --git a/Assemble.c b/Assemble.c
index 014d644..d4398b6 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -144,7 +144,7 @@ int Assemble(struct supertype *st, char *mddev,
                               * recent as everything else in the array.
                               */
                struct mdinfo i;
-       } *devices;
+       } *devices = NULL;
        int *best = NULL; /* indexed by raid_disk */
        unsigned int bestcnt = 0;
        int devcnt = 0;
@@ -547,7 +547,8 @@ int Assemble(struct supertype *st, char *mddev,
                            chosen_name);
        if (mdfd < 0) {
                st->ss->free_super(st);
-               free(devices);
+               if (devices) free(devices);
+               devices = NULL;
                if (auto_assem)
                        goto try_again;
                return 1;
@@ -573,7 +574,8 @@ int Assemble(struct supertype *st, char *mddev,
                close(mdfd);
                mdfd = -3;
                st->ss->free_super(st);
-               free(devices);
+               if (devices) free(devices);
+               devices = NULL;
                if (auto_assem)
                        goto try_again;
                return 1;
@@ -1282,9 +1284,11 @@ int assemble_container_content(struct supertype *st, int mdfd,
                        close(mdfd);
                        return 1;
                }
-       if (sra)
+       if (sra) {
                sysfs_free(sra);
-
+               sra = NULL;
+       }
+
        for (dev = content->devs; dev; dev = dev->next)
                if (sysfs_add_disk(content, dev, 1) == 0)
                        working++;
diff --git a/Create.c b/Create.c
index 7714828..2fde319 100644
--- a/Create.c
+++ b/Create.c
@@ -109,7 +109,7 @@ int Create(struct supertype *st, char *mddev,
        int container_fd = -1;
        int need_mdmon = 0;
        unsigned long long bitmapsize;
-       struct mdinfo info, *infos;
+       struct mdinfo info, *infos = NULL;
        int did_default = 0;
        int do_default_layout = 0;
        unsigned long safe_mode_delay = 0;
@@ -434,7 +434,7 @@ int Create(struct supertype *st, char *mddev,
                warn = 1;
        }

-       if (st->ss->detail_platform && st->ss->detail_platform(0, 1) != 0) {
+       if (st && st->ss->detail_platform && st->ss->detail_platform(0, 1) != 0) {
                if (runstop != 1 || verbose >= 0)
                        fprintf(stderr, Name ": %s unable to enumerate platform support\n"
                                "    array may not be compatible with hardware/firmware\n",
@@ -628,7 +628,7 @@ int Create(struct supertype *st, char *mddev,
                        fprintf(stderr, Name ": Creating array inside "
                                "%s container %s\n",
                                mdi?mdi->text_version:"managed", path);
-                       sysfs_free(mdi);
+                       if (mdi) sysfs_free(mdi);
                } else
                        fprintf(stderr, Name ": Defaulting to version"
                                " %s metadata\n", info.text_version);
@@ -850,14 +850,14 @@ int Create(struct supertype *st, char *mddev,
                                map_update(&map, st->container_dev,
                                           info_new.text_version,
                                           info_new.uuid, path);
-                               free(path);
+                               if (path) free(path);
                        }
                        map_unlock(&map);

                        flush_metadata_updates(st);
                }
        }
-       free(infos);
+       if (infos) free(infos);
        st->ss->free_super(st);

        if (level == LEVEL_CONTAINER) {
diff --git a/Detail.c b/Detail.c
index ba07c83..7f6460c 100644
--- a/Detail.c
+++ b/Detail.c
@@ -37,7 +37,7 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
        int fd = open(dev, O_RDONLY);
        int vers;
        mdu_array_info_t array;
-       mdu_disk_info_t *disks;
+       mdu_disk_info_t *disks = NULL;
        int next;
        int d;
        time_t atime;
@@ -51,7 +51,7 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
        struct supertype *st = NULL;
        int max_disks = MD_SB_DISKS; /* just a default */
        struct mdinfo info;
-       struct mdinfo *sra;
+       struct mdinfo *sra = NULL;
        char *member = NULL;
        char *container = NULL;

@@ -413,7 +413,7 @@ This is pretty boring
                        printf("  Member Arrays :");

                        while (dir && (de = readdir(dir)) != NULL) {
-                               char path[200];
+                               char path[512];
                                char vbuf[1024];
                                int nlen = strlen(sra->sys_name);
                                int dn;
@@ -550,7 +550,10 @@ This is pretty boring
                    1, avail, avail_disks))
                rv = 2;

-       free(disks);
+       if (disks) {
+               free(disks);
+               disks = NULL;
+       }
 out:
        close(fd);
        return rv;
diff --git a/Grow.c b/Grow.c
index aa6c3b3..9db851b 100644
--- a/Grow.c
+++ b/Grow.c
@@ -541,7 +541,10 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
                return 1;
        }
        sra = sysfs_read(fd, 0, GET_VERSION | GET_LEVEL | GET_DEVS | GET_STATE);
-       frozen = freeze_array(sra);
+       if (sra)
+               frozen = freeze_array(sra);
+       else
+               frozen = -1;
        if (frozen < 0) {
                fprintf(stderr, Name ": %s is performing resync/recovery and cannot"
                        " be reshaped\n", devname);
@@ -778,6 +781,8 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
                        }
                        err = sysfs_set_str(sra, NULL, "level", c);
                        if (err) {
+                               st->ss->free_super(st);
+                               st = NULL;
                                fprintf(stderr, Name ": %s: could not set level to %s\n",
                                        devname, c);
                                rv = 1;
@@ -807,6 +812,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
                                        ping_monitor(devnum2devname(dn));
                                }
                        }
+
                }
        }

@@ -932,6 +938,11 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
                 */
                st = super_by_fd(fd);

+               if (!st) {
+                       fprintf(stderr, Name ": cannot handle arrays with superblock version %d\n", array.major_version);
+                       return 1;
+               }
+
                /*
                 * There are three possibilities.
                 * 1/ The array will shrink.
@@ -1305,6 +1316,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
                                        fprintf(stderr, Name ": %s: could not set level to %s\n",
                                                devname, c);
                        }
+                       sysfs_free(sra);
                        exit(0);
                case -1:
                        fprintf(stderr, Name ": Cannot run child to monitor reshape: %s\n",
@@ -1326,8 +1338,11 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
                if (c && sysfs_set_str(sra, NULL, "level", c) == 0)
                        fprintf(stderr, Name ": aborting level change\n");
        }
-       if (sra)
+       if (sra) {
                unfreeze_array(sra, frozen);
+               sysfs_free(sra);
+       }
+
        return rv;
 }

@@ -1622,7 +1637,10 @@ static int child_grow(int afd, struct mdinfo *sra, unsigned long stripes,
                    dests, destfd, destoffsets,
                    0);
        sysfs_set_num(sra, NULL, "suspend_lo", (stripes * chunk/512) * data);
-       free(buf);
+       if (buf) {
+               free(buf);
+               buf = NULL;
+       }
        /* FIXME this should probably be numeric */
        sysfs_set_str(sra, NULL, "sync_max", "max");
        return 1;
@@ -1657,7 +1675,10 @@ static int child_shrink(int afd, struct mdinfo *sra, unsigned long stripes,
        wait_backup(sra, start, stripes*chunk/512, 0,
                    dests, destfd, destoffsets, 0);
        sysfs_set_num(sra, NULL, "suspend_lo", (stripes * chunk/512) * data);
-       free(buf);
+       if (buf) {
+               free(buf);
+               buf = NULL;
+       }
        /* FIXME this should probably be numeric */
        sysfs_set_str(sra, NULL, "sync_max", "max");
        return 1;
@@ -1728,7 +1749,10 @@ static int child_same_size(int afd, struct mdinfo *sra, unsigned long stripes,
                    1-part);
        sysfs_set_num(sra, NULL, "suspend_lo", (size*chunk/512) * data);
        sysfs_set_num(sra, NULL, "sync_speed_min", speed);
-       free(buf);
+       if (buf) {
+               free(buf);
+               buf = NULL;
+       }
        return 1;
 }

@@ -1889,6 +1913,11 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt

                /* Now need the data offsets for all devices. */
                offsets = malloc(sizeof(*offsets)*info->array.raid_disks);
+               if (offsets == NULL) {
+                       fprintf(stderr, Name ": Failed to get memory.\n");
+                       continue;
+               }
+
                for(j=0; j<info->array.raid_disks; j++) {
                        if (fdlist[j] < 0)
                                continue;
@@ -2071,7 +2100,6 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
                         GET_COMPONENT|GET_DEVS|GET_OFFSET|GET_STATE|
                         GET_CACHE);

-
        if (ndata == odata)
                while (blocks * 32 < sra->component_size &&
                       blocks < 16*1024*2)
@@ -2101,6 +2129,12 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
        backup_offsets[0] = 8 * 512;
        fds = malloc(odisks * sizeof(fds[0]));
        offsets = malloc(odisks * sizeof(offsets[0]));
+
+       if ((fds == NULL) || (offsets == NULL)) {
+               fprintf(stderr, Name ": malloc failed: grow aborted\n");
+               return 1;
+       }
+
        for (d=0; d<odisks; d++)
                fds[d] = -1;

diff --git a/Incremental.c b/Incremental.c
index 8c686f7..ded593e 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -84,10 +84,10 @@ int Incremental(char *devname, int verbose, int runstop,
        int rv;
        struct map_ent *mp, *map = NULL;
        int dfd, mdfd;
-       char *avail;
+       char *avail = NULL;
        int active_disks;
        int trustworthy = FOREIGN;
-       char *name_to_use;
+       char *name_to_use = NULL;;
        mdu_array_info_t ainf;

        struct createinfo *ci = conf_get_create_info();
@@ -334,6 +334,7 @@ int Incremental(char *devname, int verbose, int runstop,
                }
                info.array.working_disks = 1;
                sysfs_free(sra);
+               sra = NULL;
                /* 6/ Make sure /var/run/mdadm.map contains this array. */
                map_update(&map, fd2devnum(mdfd),
                           info.text_version,
@@ -441,7 +442,10 @@ int Incremental(char *devname, int verbose, int runstop,
                   info.array.layout, info.array.state & 1,
                   avail, active_disks) == 0 ||
            (runstop < 0 && active_disks < info.array.raid_disks)) {
-               free(avail);
+               if (avail) {
+                       free(avail);
+                       avail = NULL;
+               }
                if (verbose >= 0)
                        fprintf(stderr, Name
                             ": %s attached to %s, not enough to start (%d).\n",
@@ -450,7 +454,10 @@ int Incremental(char *devname, int verbose, int runstop,
                close(mdfd);
                return 0;
        }
-       free(avail);
+       if (avail) {
+               free(avail);
+               avail = NULL;
+       }

        /* 7b/ if yes, */
        /* - if number of OK devices match expected, or -R and there */
@@ -736,7 +743,7 @@ static char *container2devname(char *devname)
                mp = map_by_uuid(&map, uuid);
                if (mp)
                        mdname = devnum2devname(mp->devnum);
-               map_free(map);
+               if (map) map_free(map);
        }

        return mdname;
@@ -782,7 +789,7 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
                        } else
                                array_list = NULL;
                        for(; array_list ; array_list = array_list->next) {
-                               char *dn;
+                               char *dn = NULL;
                                if (array_list->member == NULL ||
                                    array_list->container == NULL)
                                        continue;
@@ -797,10 +804,17 @@ int Incremental_container(struct supertype *st, char *devname, int verbose,
                                if (strncmp(dn, ra->text_version+1,
                                            strlen(dn)) != 0 ||
                                    ra->text_version[strlen(dn)+1] != '/') {
+                                       if (dn) {
+                                               free(dn);
+                                               dn = NULL;
+                                       }
+                                       continue;
+                               }
+                               if (dn) {
                                        free(dn);
+                                       dn = NULL;
                                        continue;
                                }
-                               free(dn);
                                /* we have a match */
                                match = array_list;
                                if (verbose>0)
diff --git a/Manage.c b/Manage.c
index 749fa7c..0b991d0 100644
--- a/Manage.c
+++ b/Manage.c
@@ -85,7 +85,7 @@ int Manage_ro(char *devname, int fd, int readonly)
                        sysfs_set_str(mdi, NULL, "metadata_version", vers);

                        cp = strchr(vers+10, '/');
-                       if (*cp)
+                       if (cp && *cp)
                                *cp = 0;
                        ping_monitor(vers+10);
                }
@@ -123,12 +123,12 @@ static void remove_devices(int devnum, char *path)
         * partition suffixes - which link to those names.
         */
        char base[40];
-       char *path2;
+       char *path2 = NULL;
        char link[1024];
        int n;
        int part;
-       char *be;
-       char *pe;
+       char *be = NULL;
+       char *pe = NULL;

        if (devnum >= 0)
                sprintf(base, "/dev/md%d", devnum);
@@ -137,15 +137,17 @@ static void remove_devices(int devnum, char *path)
        be = base + strlen(base);
        if (path) {
                path2 = malloc(strlen(path)+20);
-               strcpy(path2, path);
-               pe = path2 + strlen(path2);
+               if (path2) {
+                       strcpy(path2, path);
+                       pe = path2 + strlen(path2);
+               }
        } else
                path2 = path = NULL;

        for (part = 0; part < 16; part++) {
                if (part) {
                        sprintf(be, "p%d", part);
-                       if (path) {
+                       if ((path) && (pe)) {
                                if (isdigit(pe[-1]))
                                        sprintf(pe, "p%d", part);
                                else
@@ -154,14 +156,15 @@ static void remove_devices(int devnum, char *path)
                }
                /* FIXME test if really is md device ?? */
                unlink(base);
-               if (path) {
+               if ((path) && (path2)) {
                        n = readlink(path2, link, sizeof(link));
                        if (n && strlen(base) == n &&
                            strncmp(link, base, n) == 0)
                                unlink(path2);
                }
        }
-       free(path2);
+       if (path2)
+               free(path2);
 }


@@ -356,7 +359,7 @@ int Manage_subdevs(char *devname, int fd,

        for (dv = devlist, j=0 ; dv; dv = next, j = jnext) {
                unsigned long long ldsize;
-               char dvname[20];
+               char dvname[30];
                char *dnprintable = dv->devname;
                int err;

@@ -637,29 +640,32 @@ int Manage_subdevs(char *devname, int fd,
                                 * to fill.
                                 */
                                char *used = malloc(array.raid_disks);
-                               memset(used, 0, array.raid_disks);
-                               for (j=0; j< tst->max_devs; j++) {
-                                       mdu_disk_info_t disc2;
-                                       disc2.number = j;
-                                       if (ioctl(fd, GET_DISK_INFO, &disc2))
-                                               continue;
-                                       if (disc2.major==0 && disc2.minor==0)
-                                               continue;
-                                       if (disc2.state & 8) /* removed */
-                                               continue;
-                                       if (disc2.raid_disk < 0)
-                                               continue;
-                                       if (disc2.raid_disk > array.raid_disks)
-                                               continue;
-                                       used[disc2.raid_disk] = 1;
-                               }
-                               for (j=0 ; j<array.raid_disks; j++)
-                                       if (!used[j]) {
-                                               disc.raid_disk = j;
-                                               disc.state |= (1<<MD_DISK_SYNC);
-                                               break;
+                               if (used) {
+                                       memset(used, 0, array.raid_disks);
+                                       for (j=0; j< tst->max_devs; j++) {
+                                               mdu_disk_info_t disc2;
+                                               disc2.number = j;
+                                               if (ioctl(fd, GET_DISK_INFO, &disc2))
+                                                       continue;
+                                               if (disc2.major==0 && disc2.minor==0)
+                                                       continue;
+                                               if (disc2.state & 8) /* removed */
+                                                       continue;
+                                               if (disc2.raid_disk < 0)
+                                                       continue;
+                                               if (disc2.raid_disk > array.raid_disks)
+                                                       continue;
+                                               used[disc2.raid_disk] = 1;
                                        }
-                               free(used);
+                                       for (j=0 ; j<array.raid_disks; j++)
+                                               if (!used[j]) {
+                                                       disc.raid_disk = j;
+                                                       disc.state |= (1<<MD_DISK_SYNC);
+                                                       break;
+                                               }
+                                       free(used);
+                                       used = NULL;
+                               }
                        }
                        if (dv->writemostly == 1)
                                disc.state |= (1 << MD_DISK_WRITEMOSTLY);
@@ -706,8 +712,10 @@ int Manage_subdevs(char *devname, int fd,
                                        close(container_fd);
                                        return 1;
                                }
+
                                ping_monitor(devnum2devname(devnum));
                                sysfs_free(sra);
+                               sra = NULL;
                                close(container_fd);
                        } else if (ioctl(fd, ADD_NEW_DISK, &disc)) {
                                fprintf(stderr, Name ": add new device failed for %s as %d: %s\n",
@@ -779,8 +787,10 @@ int Manage_subdevs(char *devname, int fd,
                                                            "state", "remove");
                                else
                                        err = -1;
-                               if (sra)
+                               if (sra) {
                                        sysfs_free(sra);
+                                       sra = NULL;
+                               }
                        }
                        if (err) {
                                fprintf(stderr, Name ": hot remove failed "
diff --git a/Monitor.c b/Monitor.c
index b0802f8..4d0fd8f 100644
--- a/Monitor.c
+++ b/Monitor.c
@@ -152,7 +152,7 @@ int Monitor(mddev_dev_t devlist,
        if (devlist == NULL) {
                mddev_ident_t mdlist = conf_get_ident(NULL);
                for (; mdlist; mdlist=mdlist->next) {
-                       struct state *st;
+                       struct state *st = NULL;
                        if (mdlist->devname == NULL)
                                continue;
                        if (strcasecmp(mdlist->devname, "<ignore>") == 0)
@@ -164,6 +164,7 @@ int Monitor(mddev_dev_t devlist,
                                st->devname = strdup(mdlist->devname);
                        else {
                                st->devname = malloc(8+strlen(mdlist->devname)+1);
+                               if (st->devname == NULL) continue;
                                strcpy(strcpy(st->devname, "/dev/md/"),
                                       mdlist->devname);
                        }
@@ -206,7 +207,7 @@ int Monitor(mddev_dev_t devlist,

        while (! finished) {
                int new_found = 0;
-               struct state *st;
+               struct state *st = NULL;

                if (mdstat)
                        free_mdstat(mdstat);
@@ -330,8 +331,10 @@ int Monitor(mddev_dev_t devlist,
                                        alert("RebuildFinished", dev, cnt, mailaddr, mailfrom, alert_cmd, dosyslog);
                                } else
                                        alert("RebuildFinished", dev, NULL, mailaddr, mailfrom, alert_cmd, dosyslog);
-                               if (sra)
+                               if (sra) {
                                        free(sra);
+                                       sra = NULL;
+                               }
                        }

                        if (mse)
@@ -428,8 +431,14 @@ int Monitor(mddev_dev_t devlist,
                                                /* no such array */
                                                if (fd >=0) close(fd);
                                                put_md_name(st->devname);
-                                               free(st->devname);
-                                               free(st);
+                                               if (st) {
+                                                       if (st->devname) {
+                                                               free(st->devname);
+                                                               st->devname = NULL;
+                                                       }
+                                                       free(st);
+                                                       st = NULL;
+                                               }
                                                continue;
                                        }
                                        close(fd);
@@ -455,7 +464,7 @@ int Monitor(mddev_dev_t devlist,
                        if (st->active < st->raid &&
                            st->spare == 0 &&
                            st->spare_group != NULL) {
-                               struct state *st2;
+                               struct state *st2 = NULL;
                                for (st2=statelist ; st2 ; st2=st2->next)
                                        if (st2 != st &&
                                            st2->spare > 0 &&
@@ -481,7 +490,7 @@ int Monitor(mddev_dev_t devlist,
                                                }
                                                if (dev > 0) {
                                                        struct mddev_dev_s devlist;
-                                                       char devname[20];
+                                                       char devname[30];
                                                        devlist.next = NULL;
                                                        devlist.used = 0;
                                                        devlist.re_add = 0;
diff --git a/config.c b/config.c
index 07a12dc..06e5d5f 100644
--- a/config.c
+++ b/config.c
@@ -120,7 +120,7 @@ char *conf_word(FILE *file, int allow_key)
        int c;
        int quote;
        int wordfound = 0;
-       char *word = malloc(wsize);
+       char *word = calloc(1,wsize);

        if (!word) abort();

@@ -215,12 +215,17 @@ char *conf_line(FILE *file)

 void free_line(char *line)
 {
+
        char *w;
-       for (w=dl_next(line); w != line; w=dl_next(line)) {
-               dl_del(w);
-               dl_free(w);
+
+       if (line) {
+               for (w=dl_next(line); (w != line) && (w); w=dl_next(line)) {
+                       dl_del(w);
+                       dl_free(w);
+               }
+               dl_free(line);
        }
-       dl_free(line);
+
 }


@@ -254,11 +259,13 @@ mddev_dev_t load_partitions(void)
                name = map_dev(major, minor, 1);
                if (!name)
                        continue;
-               d = malloc(sizeof(*d));
-               d->devname = strdup(name);
-               d->next = rv;
-               d->used = 0;
-               d->content = NULL;
+               d = calloc(1,sizeof(*d));
+               if (d) {
+                       d->devname = strdup(name);
+                       d->next = rv;
+                       d->used = 0;
+                       d->content = NULL;
+               }
                rv = d;
        }
        fclose(f);
@@ -279,11 +286,12 @@ mddev_dev_t load_containers(void)
                if (ent->metadata_version &&
                    strncmp(ent->metadata_version, "external:", 9) == 0 &&
                    !is_subarray(&ent->metadata_version[9])) {
-                       d = malloc(sizeof(*d));
+                       d = calloc( 1, sizeof(*d));
                        if (!d)
                                continue;
                        if (asprintf(&d->devname, "/dev/%s", ent->dev) < 0) {
                                free(d);
+                               d = NULL;
                                continue;
                        }
                        d->next = rv;
@@ -429,10 +437,12 @@ void devline(char *line)
        for (w=dl_next(line); w != line; w=dl_next(w)) {
                if (w[0] == '/' || strcasecmp(w, "partitions") == 0 ||
                    strcasecmp(w, "containers") == 0) {
-                       cd = malloc(sizeof(*cd));
-                       cd->name = strdup(w);
-                       cd->next = cdevlist;
-                       cdevlist = cd;
+                       cd = calloc(1, sizeof(*cd));
+                       if (cd) {
+                               cd->name = strdup(w);
+                               cd->next = cdevlist;
+                               cdevlist = cd;
+                       }
                } else {
                        fprintf(stderr, Name ": unreconised word on DEVICE line: %s\n",
                                w);
@@ -600,7 +610,7 @@ void arrayline(char *line)
            (mis.container == NULL || mis.member == NULL))
                fprintf(stderr, Name ": ARRAY line %s has no identity information.\n", mis.devname);
        else {
-               mi = malloc(sizeof(*mi));
+               mi = calloc(1, sizeof(*mi));
                *mi = mis;
                mi->devname = mis.devname ? strdup(mis.devname) : NULL;
                mi->next = NULL;
@@ -721,6 +731,7 @@ void load_conffile(void)
                dl_add(list, dl_strdup("partitions"));
                devline(list);
                free_line(list);
+               list = NULL;
                loaded = 1;
                return;
        }
@@ -770,6 +781,7 @@ void load_conffile(void)
                        fprintf(stderr, Name ": Unknown keyword %s\n", line);
                }
                free_line(line);
+               line = NULL;
        }

        fclose(f);
@@ -839,7 +851,9 @@ mddev_dev_t conf_get_devs()
                mddev_dev_t t = dlist;
                dlist = dlist->next;
                free(t->devname);
+               t->devname = NULL;
                free(t);
+               t = NULL;
        }

        load_conffile();
@@ -862,7 +876,7 @@ mddev_dev_t conf_get_devs()
        }
        if (flags & GLOB_APPEND) {
                for (i=0; i<globbuf.gl_pathc; i++) {
-                       mddev_dev_t t = malloc(sizeof(*t));
+                       mddev_dev_t t = calloc(1,sizeof(*t));
                        t->devname = strdup(globbuf.gl_pathv[i]);
                        t->next = dlist;
                        t->used = 0;
@@ -871,6 +885,7 @@ mddev_dev_t conf_get_devs()
 /*     printf("one dev is %s\n", t->devname);*/
                }
                globfree(&globbuf);
+
        }

        return dlist;
diff --git a/dlink.c b/dlink.c
index d734281..f99cb1d 100644
--- a/dlink.c
+++ b/dlink.c
@@ -22,8 +22,16 @@ void *dl_head()

 void dl_free(void *v)
 {
-    struct __dl_head *vv  = v;
-    free(vv-1);
+       struct __dl_head *vv;
+
+       if (v) {
+               vv  = v;
+               vv = vv-1;
+               if (vv) {
+                       free(vv);
+                       (vv) = NULL;
+               }
+       }
 }

 void dl_init(void *v)
@@ -75,5 +83,8 @@ char *dl_strndup(char *s, int l)

 char *dl_strdup(char *s)
 {
-    return dl_strndup(s, (int)strlen(s));
+    if (s)
+       return dl_strndup(s, (int)strlen(s));
+    else
+       return NULL;
 }
diff --git a/managemon.c b/managemon.c
index 86816c4..a1b6a0b 100644
--- a/managemon.c
+++ b/managemon.c
@@ -113,13 +113,16 @@ static void close_aa(struct active_array *aa)
        struct mdinfo *d;

        for (d = aa->info.devs; d; d = d->next) {
-               close(d->recovery_fd);
                close(d->state_fd);
+               d->state_fd = -1;
        }

        close(aa->action_fd);
+       aa->action_fd = -1;
        close(aa->info.state_fd);
+       aa->info.state_fd = -1;
        close(aa->resync_start_fd);
+       aa->resync_start_fd = -1;
 }

 static void free_aa(struct active_array *aa)
@@ -128,14 +131,24 @@ static void free_aa(struct active_array *aa)
         * by a clone.  ->container will be set for a clone
         */
        dprintf("%s: devnum: %d\n", __func__, aa->devnum);
-       if (!aa->container)
-               close_aa(aa);
-       while (aa->info.devs) {
-               struct mdinfo *d = aa->info.devs;
-               aa->info.devs = d->next;
-               free(d);
+
+       if (aa) {
+               if (!aa->container)
+                       close_aa(aa);
+
+               while (aa->info.devs) {
+                       struct mdinfo *d = aa->info.devs;
+                       if (d) {
+                               aa->info.devs = d->next;
+                               free(d);
+                               d = NULL;
+                       }
+               }
+
+               free(aa);
+               aa = NULL;
        }
-       free(aa);
+
 }

 static struct active_array *duplicate_aa(struct active_array *aa)
@@ -143,24 +156,28 @@ static struct active_array *duplicate_aa(struct active_array *aa)
        struct active_array *newa = malloc(sizeof(*newa));
        struct mdinfo **dp1, **dp2;

-       *newa = *aa;
-       newa->next = NULL;
-       newa->replaces = NULL;
-       newa->info.next = NULL;
+       if (newa) {
+               *newa = *aa;
+               newa->next = NULL;
+               newa->replaces = NULL;
+               newa->info.next = NULL;

-       dp2 = &newa->info.devs;
+               dp2 = &newa->info.devs;

-       for (dp1 = &aa->info.devs; *dp1; dp1 = &(*dp1)->next) {
-               struct mdinfo *d;
-               if ((*dp1)->state_fd < 0)
-                       continue;
+               for (dp1 = &aa->info.devs; *dp1; dp1 = &(*dp1)->next) {
+                       struct mdinfo *d;
+                       if ((*dp1)->state_fd < 0)
+                               continue;

-               d = malloc(sizeof(*d));
-               *d = **dp1;
-               *dp2 = d;
-               dp2 = & d->next;
-       }
+                       d = malloc(sizeof(*d));
+                       if (d) {
+                               *d = **dp1;
+                               *dp2 = d;
+                               dp2 = & d->next;
+                       }
+               }
        *dp2 = NULL;
+       }

        return newa;
 }
@@ -248,7 +265,7 @@ static void queue_metadata_update(struct metadata_update *mu)
 static void add_disk_to_container(struct supertype *st, struct mdinfo *sd)
 {
        int dfd;
-       char nm[20];
+       char nm[30];
        struct supertype *st2;
        struct metadata_update *update = NULL;
        struct mdinfo info;
@@ -275,20 +292,23 @@ static void add_disk_to_container(struct supertype *st, struct mdinfo *sd)
         * array
         */
        st2 = dup_super(st);
-       if (st2->ss->load_super(st2, dfd, NULL) == 0) {
-               st2->ss->getinfo_super(st, &info);
-               if (st->ss->compare_super(st, st2) == 0 &&
-                   info.disk.raid_disk >= 0) {
-                       /* Looks like a good member of array.
-                        * Just accept it.
-                        * mdadm will incorporate any parts into
-                        * active arrays.
-                        */
-                       st2->ss->free_super(st2);
-                       return;
+
+       if (st2 != NULL) {
+               if (st2->ss->load_super(st2, dfd, NULL) == 0) {
+                       st2->ss->getinfo_super(st, &info);
+                       if (st->ss->compare_super(st, st2) == 0 &&
+                           info.disk.raid_disk >= 0) {
+                               /* Looks like a good member of array.
+                                * Just accept it.
+                                * mdadm will incorporate any parts into
+                                * active arrays.
+                                */
+                               st2->ss->free_super(st2);
+                               return;
+                       }
                }
+               st2->ss->free_super(st2);
        }
-       st2->ss->free_super(st2);

        st->update_tail = &update;
        st->ss->add_to_super(st, &dk, dfd, NULL);
@@ -335,6 +355,7 @@ static void manage_container(struct mdstat_ent *mdstat,
                                cd = *cdp;
                                *cdp = (*cdp)->next;
                                free(cd);
+                               cd = NULL;
                        } else
                                cdp = &(*cdp)->next;
                }
@@ -357,6 +378,7 @@ static void manage_container(struct mdstat_ent *mdstat,
                        }
                }
                sysfs_free(mdi);
+               mdi = NULL;
                container->devcnt = mdstat->devcnt;
        }
 }
@@ -491,14 +513,18 @@ static void manage_new(struct mdstat_ent *mdstat,
        mdi = sysfs_read(-1, mdstat->devnum,
                         GET_LEVEL|GET_LAYOUT|GET_CHUNK|GET_DISKS|GET_COMPONENT|
                         GET_DEGRADED|GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE);
-
+
        new = malloc(sizeof(*new));

        if (!new || !mdi) {
-               if (mdi)
+               if (mdi) {
                        sysfs_free(mdi);
-               if (new)
+                       mdi = NULL;
+               }
+               if (new) {
                        free(new);
+                       new = NULL;
+               }
                return;
        }
        memset(new, 0, sizeof(*new));
@@ -536,8 +562,10 @@ static void manage_new(struct mdstat_ent *mdstat,
                        newd->prev_state = read_dev_state(newd->state_fd);
                        newd->curr_state = newd->prev_state;
                } else {
-                       if (newd)
+                       if (newd) {
                                free(newd);
+                               newd = NULL;
+                       }

                        failed++;
                        if (failed > new->info.array.failed_disks) {
@@ -559,12 +587,12 @@ static void manage_new(struct mdstat_ent *mdstat,
        new->level_fd = sysfs_open(new->devnum, NULL, "level");
        new->takeover = none;
        new->prev_level  = -1;
-
        dprintf("%s: inst: %d action: %d state: %d\n", __func__, atoi(inst),
                new->action_fd, new->info.state_fd);

        sysfs_free(mdi);
-
+       mdi = NULL;
+
        /* if everything checks out tell the metadata handler we want to
         * manage this instance
         */
@@ -642,14 +670,16 @@ static void handle_message(struct supertype *container, struct metadata_update *
                free_mdstat(mdstat);
        } else if (!sigterm) {
                mu = malloc(sizeof(*mu));
-               mu->len = msg->len;
-               mu->buf = msg->buf;
-               msg->buf = NULL;
-               mu->space = NULL;
-               mu->next = NULL;
-               if (container->ss->prepare_update)
-                       container->ss->prepare_update(container, mu);
-               queue_metadata_update(mu);
+               if (mu) {
+                       mu->len = msg->len;
+                       mu->buf = msg->buf;
+                       msg->buf = NULL;
+                       mu->space = NULL;
+                       mu->next = NULL;
+                       if (container->ss->prepare_update)
+                               container->ss->prepare_update(container, mu);
+                       queue_metadata_update(mu);
+               }
        }
 }

@@ -701,7 +731,8 @@ void do_manager(struct supertype *container)
        proc_fd = open("/proc/mounts", O_RDONLY);

        do {
-
+               check_update_queue(container);
+
                if (exit_now)
                        exit(0);

diff --git a/mapfile.c b/mapfile.c
index ed59db5..3bf0dab 100644
--- a/mapfile.c
+++ b/mapfile.c
@@ -121,8 +121,10 @@ int map_lock(struct map_ent **melp)
                        return -1;
                }
        }
-       if (*melp)
+       if (*melp) {
                map_free(*melp);
+               *melp = NULL;
+       }
        map_read(melp);
        return 0;
 }
@@ -189,8 +191,12 @@ void map_free(struct map_ent *map)
        while (map) {
                struct map_ent *mp = map;
                map = mp->next;
-               free(mp->path);
+               if (mp->path) {
+                       free(mp->path);
+                       mp->path = NULL;
+               }
                free(mp);
+               mp = NULL;
        }
 }

@@ -209,7 +215,7 @@ int map_update(struct map_ent **mpp, int devnum, char *metadata,
                if (mp->devnum == devnum) {
                        strcpy(mp->metadata, metadata);
                        memcpy(mp->uuid, uuid, 16);
-                       free(mp->path);
+                       if (mp->path) free(mp->path);
                        mp->path = path ? strdup(path) : NULL;
                        break;
                }
@@ -218,7 +224,7 @@ int map_update(struct map_ent **mpp, int devnum, char *metadata,
        if (mpp)
                *mpp = NULL;
        rv = map_write(map);
-       map_free(map);
+       if (map) map_free(map);
        return rv;
 }

@@ -232,8 +238,12 @@ void map_delete(struct map_ent **mapp, int devnum)
        for (mp = *mapp; mp; mp = *mapp) {
                if (mp->devnum == devnum) {
                        *mapp = mp->next;
-                       free(mp->path);
+                       if (mp->path) {
+                               free(mp->path);
+                               mp->path = NULL;
+                       }
                        free(mp);
+                       mp = NULL;
                } else
                        mapp = & mp->next;
        }
@@ -458,13 +468,16 @@ void RebuildMap(void)
                        break;
                }
                sysfs_free(sra);
+               sra = NULL;
        }
        map_write(map);
        map_free(map);
+       map = NULL;
        for (md = mdstat ; md ; md = md->next) {
                struct mdinfo *sra = sysfs_read(-1, md->devnum, GET_VERSION);
                sysfs_uevent(sra, "change");
                sysfs_free(sra);
+               sra = NULL;
        }
        free_mdstat(mdstat);
 }
diff --git a/mdmon.c b/mdmon.c
index 0ec4259..5813e21 100644
--- a/mdmon.c
+++ b/mdmon.c
@@ -64,8 +64,8 @@
 #include       "mdadm.h"
 #include       "mdmon.h"

-struct active_array *discard_this;
-struct active_array *pending_discard;
+struct active_array *discard_this = NULL;
+struct active_array *pending_discard = NULL;

 int mon_tid, mgr_tid;

@@ -125,7 +125,7 @@ static int test_pidfile(char *devname)
 int make_pidfile(char *devname, int o_excl)
 {
        char path[100];
-       char pid[10];
+       char pid[20];
        int fd;
        int n;

@@ -477,6 +477,7 @@ int mdmon(char *devname, int devnum, int scan, char *switchroot)
                container->devs = cd;
        }
        sysfs_free(mdi);
+       mdi = NULL;

        /* SIGUSR is sent between parent and child.  So both block it
         * and enable it only with pselect.
diff --git a/mdopen.c b/mdopen.c
index 21baf5d..b3b0cf6 100644
--- a/mdopen.c
+++ b/mdopen.c
@@ -43,7 +43,7 @@ void make_parts(char *dev, int cnt)
        int odig = odig; /* quiet gcc -Os unitialized warning */
        int i;
        int nlen = strlen(dev) + 20;
-       char *name;
+       char *name = NULL;
        int dig = isdigit(dev[strlen(dev)-1]);
        char orig[1024];
        char sym[1024];
@@ -94,7 +94,7 @@ void make_parts(char *dev, int cnt)
                if (err == 0 && stat(name, &stb2) == 0)
                        add_dev(name, &stb2, 0, NULL);
        }
-       free(name);
+       if (name) free(name);
 }


diff --git a/mdstat.c b/mdstat.c
index 4d2f473..d7045a7 100644
--- a/mdstat.c
+++ b/mdstat.c
@@ -87,13 +87,26 @@ void free_mdstat(struct mdstat_ent *ms)
 {
        while (ms) {
                struct mdstat_ent *t;
-               if (ms->dev) free(ms->dev);
-               if (ms->level) free(ms->level);
-               if (ms->pattern) free(ms->pattern);
-               if (ms->metadata_version) free(ms->metadata_version);
+               if (ms->dev) {
+                       free(ms->dev);
+                       ms->dev=NULL;
+               }
+               if (ms->level) {
+                       free(ms->level);
+                       ms->level = NULL;
+               }
+               if (ms->pattern) {
+                       free(ms->pattern);
+                       ms->pattern = NULL;
+               }
+               if (ms->metadata_version) {
+                       free(ms->metadata_version);
+                       ms->metadata_version = NULL;
+               }
                t = ms;
                ms = ms->next;
                free(t);
+               t = NULL;
        }
 }

@@ -102,7 +115,7 @@ struct mdstat_ent *mdstat_read(int hold, int start)
 {
        FILE *f;
        struct mdstat_ent *all, *rv, **end, **insert_here;
-       char *line;
+       char *line = NULL;

        if (hold && mdstat_fd != -1) {
                lseek(mdstat_fd, 0L, 0);
@@ -148,6 +161,7 @@ struct mdstat_ent *mdstat_read(int hold, int start)
                if (!ent) {
                        fprintf(stderr, Name ": malloc failed reading /proc/mdstat.\n");
                        free_line(line);
+                       line = NULL;
                        break;
                }
                ent->dev = ent->level = ent->pattern= NULL;
diff --git a/monitor.c b/monitor.c
index ea87f5f..c4f4015 100644
--- a/monitor.c
+++ b/monitor.c
@@ -17,10 +17,14 @@
  * this program; if not, write to the Free Software Foundation, Inc.,
  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
  */
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif

 #include "mdadm.h"
 #include "mdmon.h"
 #include <sys/syscall.h>
+#include <sys/socket.h>
 #include <sys/select.h>
 #include <signal.h>

diff --git a/msg.c b/msg.c
index 8d52b94..1e23b01 100644
--- a/msg.c
+++ b/msg.c
@@ -111,14 +111,20 @@ int receive_message(int fd, struct metadata_update *msg, int tmo)
                        return -1;
                rv = recv_buf(fd, msg->buf, len, tmo);
                if (rv < 0) {
-                       free(msg->buf);
+                       if (msg->buf) {
+                               free(msg->buf);
+                               msg->buf = NULL;
+                       }
                        return -1;
                }
        } else
                msg->buf = NULL;
        rv = recv_buf(fd, &magic, 4, tmo);
        if (rv < 0 || magic != end_magic) {
-               free(msg->buf);
+               if (msg->buf) {
+                       free(msg->buf);
+                       msg->buf = NULL;
+               }
                return -1;
        }
        msg->len = len;
diff --git a/platform-intel.c b/platform-intel.c
index 30f7914..e853a10 100644
--- a/platform-intel.c
+++ b/platform-intel.c
@@ -35,7 +35,10 @@ void free_sys_dev(struct sys_dev **list)
                struct sys_dev *next = (*list)->next;

                if ((*list)->path)
+               {
                        free((*list)->path);
+                       (*list)->path = NULL;
+               }
                free(*list);
                *list = next;
        }
@@ -44,8 +47,8 @@ void free_sys_dev(struct sys_dev **list)
 struct sys_dev *find_driver_devices(const char *bus, const char *driver)
 {
        /* search sysfs for devices driven by 'driver' */
-       char path[292];
-       char link[256];
+       char path[1024];
+       char link[1024];
        char *c;
        DIR *driver_dir;
        struct dirent *de;
@@ -206,7 +209,7 @@ const struct imsm_orom *find_imsm_orom(void)

 char *devt_to_devpath(dev_t dev)
 {
-       char device[46];
+       char device[50];

        sprintf(device, "/sys/dev/block/%d:%d/device", major(dev), minor(dev));
        return canonicalize_file_name(device);
diff --git a/restripe.c b/restripe.c
index f673206..7d8809b 100644
--- a/restripe.c
+++ b/restripe.c
@@ -573,10 +573,14 @@ int restore_stripes(int *dest, unsigned long long *offsets,
        }
        if (stripe_buf == NULL || stripes == NULL || blocks == NULL
            || zero == NULL) {
-               free(stripe_buf);
-               free(stripes);
-               free(blocks);
-               free(zero);
+               if (stripe_buf)
+                       free(stripe_buf);
+               if (stripes)
+                       free(stripes);
+               if (blocks)
+                       free(blocks);
+               if (zero)
+                       free(zero);
                return -2;
        }
        for (i=0; i<raid_disks; i++)
diff --git a/super-intel.c b/super-intel.c
index be7fac9..9e82f0c 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -633,23 +633,35 @@ static __u32 imsm_reserved_sectors(struct intel_super *super, struct dl *dl)
        rv = __le32_to_cpu(dl->disk.total_blocks) - e[i].start;

        free(e);
+       e=NULL;

        return rv;
 }

 static int is_spare(struct imsm_disk *disk)
 {
-       return (disk->status & SPARE_DISK) == SPARE_DISK;
+       if (disk)
+               return (disk->status & SPARE_DISK) == SPARE_DISK;
+       else
+               return 0;
 }

 static int is_configured(struct imsm_disk *disk)
 {
-       return (disk->status & CONFIGURED_DISK) == CONFIGURED_DISK;
+       if (disk)
+               return (disk->status & CONFIGURED_DISK) == CONFIGURED_DISK;
+       else
+               return 0;
+
 }

 static int is_failed(struct imsm_disk *disk)
 {
-       return (disk->status & FAILED_DISK) == FAILED_DISK;
+       if (disk)
+               return (disk->status & FAILED_DISK) == FAILED_DISK;
+       else
+               return 0;
+
 }

 #ifndef MDASSEMBLE
@@ -936,7 +948,10 @@ static int imsm_enumerate_ports(const char *hba_path, int port_count, int host_b
                                fprintf(stderr, Name ": failed to read device type for %s\n",
                                        path);
                        err = 2;
-                       free(device);
+                       if (device) {
+                               free(device);
+                               device = NULL;
+                       }
                        break;
                }
                type = strtoul(buf, NULL, 10);
@@ -980,8 +995,11 @@ static int imsm_enumerate_ports(const char *hba_path, int port_count, int host_b
                                }
                } else
                        buf[0] = '\0';
-               free(device);
-
+               if (device) {
+                       free(device);
+                       device = NULL;
+               }
+
                /* chop device path to 'host%d' and calculate the port number */
                c = strchr(&path[hba_len], '/');
                if (!c) {
@@ -1024,11 +1042,15 @@ static int imsm_enumerate_ports(const char *hba_path, int port_count, int host_b
                                printf("()\n");
                }
                close(fd);
+               if (path) {
+                       free(path);
+                       path = NULL;
+               }
+       }
+       if (path) {
                free(path);
                path = NULL;
        }
-       if (path)
-               free(path);
        if (dir)
                closedir(dir);
        if (err == 0) {
@@ -1077,13 +1099,13 @@ static int detail_platform_imsm(int verbose, int enumerate_only)
        if (!hba) {
                if (verbose)
                        fprintf(stderr, Name ": unable to find active ahci controller\n");
-               free_sys_dev(&list);
+               if (list) free_sys_dev(&list);
                return 2;
        } else if (verbose)
                fprintf(stderr, Name ": found Intel SATA AHCI Controller\n");
        hba_path = hba->path;
        hba->path = NULL;
-       free_sys_dev(&list);
+       if (list) free_sys_dev(&list);

        orom = find_imsm_orom();
        if (!orom) {
@@ -1191,7 +1213,9 @@ static void uuid_from_super_imsm(struct supertype *st, int uuid[4])
         * Hopefully these are all constant.
         */
        struct intel_super *super = st->sb;
-
+
+       if (super==NULL) return;
+
        char buf[20];
        struct sha1_ctx ctx;
        struct imsm_dev *dev = NULL;
@@ -1537,6 +1561,7 @@ static void fixup_container_spare_uuid(struct mdinfo *inf)
                        if (_sst) {
                                memcpy(inf->uuid, array_list->uuid, sizeof(int[4]));
                                free(_sst);
+                               _sst = NULL;
                                break;
                        }
                }
@@ -1548,10 +1573,14 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info)
        struct intel_super *super = st->sb;
        struct imsm_disk *disk;

-       if (super->current_vol >= 0) {
-               getinfo_super_imsm_volume(st, info);
-               return;
+       if (super) {
+               if (super->current_vol >= 0) {
+                       getinfo_super_imsm_volume(st, info);
+                       return;
+               }
        }
+       else
+               return;

        /* Set raid_disks to zero so that Assemble will always pull in valid
         * spares
@@ -1703,8 +1732,12 @@ static void free_devlist(struct intel_super *super)

        while (super->devlist) {
                dv = super->devlist->next;
-               free(super->devlist->dev);
+               if (super->devlist->dev) {
+                       free(super->devlist->dev);
+                       super->devlist->dev = NULL;
+               }
                free(super->devlist);
+               super->devlist = NULL;
                super->devlist = dv;
        }
 }
@@ -1723,7 +1756,7 @@ struct imsm_dev *reallocate_imsm_dev(struct intel_super *super,
        struct imsm_dev *retVal = NULL;
        struct intel_dev *dv = NULL;
        int memNeeded;
-
+
        if (super) {
                /* Calculate space needed for imsm_dev with a single map */
                memNeeded = sizeof(struct imsm_dev) + sizeof(__u32) * (map0_num_members - 1);
@@ -1814,6 +1847,7 @@ static int compare_super_imsm(struct supertype *st, struct supertype *tst)
                        dev = malloc(sizeof_imsm_dev(get_imsm_dev(sec, i), 1));
                        if (!dev) {
                                free(dv);
+                               dv = NULL;
                                break;
                        }
                        dv->dev = dev;
@@ -1964,11 +1998,12 @@ __serial_to_disk(__u8 *serial, struct imsm_super *mpb, int *idx)

        for (i = 0; i < mpb->num_disks; i++) {
                struct imsm_disk *disk = __get_imsm_disk(mpb, i);
-
-               if (serialcmp(disk->serial, serial) == 0) {
-                       if (idx)
-                               *idx = i;
-                       return disk;
+               if (disk) {
+                       if (serialcmp(disk->serial, serial) == 0) {
+                               if (idx)
+                                       *idx = i;
+                               return disk;
+                       }
                }
        }

@@ -2115,9 +2150,9 @@ static int parse_raid_devices(struct intel_super *super)
                dev_new = malloc(len_migr);
                if (!dev_new) {
                        free(dv);
+                       dv = NULL;
                        return 1;
                }
-
                imsm_copy_dev(dev_new, dev_iter);
                dv->dev = dev_new;
                dv->index = i;
@@ -2137,7 +2172,7 @@ static int parse_raid_devices(struct intel_super *super)

                memcpy(buf, super->buf, super->len);
                memset(buf + super->len, 0, len - super->len);
-               free(super->buf);
+               if (super->buf) free(super->buf);
                super->buf = buf;
                super->len = len;
        }
@@ -2194,6 +2229,7 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname)
                                Name ": Cannot read anchor block on %s: %s\n",
                                devname, strerror(errno));
                free(anchor);
+               anchor = NULL;
                return 1;
        }

@@ -2202,6 +2238,7 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname)
                        fprintf(stderr,
                                Name ": no IMSM anchor on %s\n", devname);
                free(anchor);
+               anchor = NULL;
                return 2;
        }

@@ -2213,12 +2250,14 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname)
                                Name ": unable to allocate %zu byte mpb buffer\n",
                                super->len);
                free(anchor);
+               anchor = NULL;
                return 2;
        }
        memcpy(super->buf, anchor, 512);

        sectors = mpb_sectors(anchor) - 1;
        free(anchor);
+       anchor = NULL;
        if (!sectors) {
                check_sum = __gen_imsm_checksum(super->anchor);
                if (check_sum != __le32_to_cpu(super->anchor->check_sum)) {
@@ -2288,28 +2327,36 @@ load_and_parse_mpb(int fd, struct intel_super *super, char *devname, int keep_fd

 static void __free_imsm_disk(struct dl *d)
 {
-       if (d->fd >= 0)
-               close(d->fd);
-       if (d->devname)
-               free(d->devname);
-       if (d->e)
-               free(d->e);
-       free(d);
-
+       if (d) {
+               if (d->fd >= 0)
+                       close(d->fd);
+               if (d->devname) {
+                       free(d->devname);
+                       d->devname = NULL;
+               }
+               if (d->e) {
+                       free(d->e);
+                       d->e = NULL;
+               }
+               free(d);
+               d = NULL;
+       }
 }
+
 static void free_imsm_disks(struct intel_super *super)
 {
        struct dl *d;
-
-       while (super->disks) {
-               d = super->disks;
-               super->disks = d->next;
-               __free_imsm_disk(d);
-       }
-       while (super->missing) {
-               d = super->missing;
-               super->missing = d->next;
-               __free_imsm_disk(d);
+       if (super) {
+               while (super->disks) {
+                       d = super->disks;
+                       super->disks = d->next;
+                       __free_imsm_disk(d);
+               }
+               while (super->missing) {
+                       d = super->missing;
+                       super->missing = d->next;
+                       __free_imsm_disk(d);
+               }
        }

 }
@@ -2317,29 +2364,39 @@ static void free_imsm_disks(struct intel_super *super)
 /* free all the pieces hanging off of a super pointer */
 static void __free_imsm(struct intel_super *super, int free_disks)
 {
-       if (super->buf) {
-               free(super->buf);
-               super->buf = NULL;
-       }
-       if (free_disks)
-               free_imsm_disks(super);
-       free_devlist(super);
-       if (super->hba) {
-               free((void *) super->hba);
-               super->hba = NULL;
+       if (super) {
+               if (super->buf) {
+                       free(super->buf);
+                       super->buf = NULL;
+               }
+               if (free_disks)
+                       free_imsm_disks(super);
+               free_devlist(super);
+               if (super->hba) {
+                       free((void *) super->hba);
+                       super->hba = NULL;
+               }
        }
 }

 static void free_imsm(struct intel_super *super)
 {
-       __free_imsm(super, 1);
-       free(super);
+       if (super) {
+               __free_imsm(super, 1);
+               free(super);
+               super = NULL;
+
+       }
 }

 static void free_super_imsm(struct supertype *st)
 {
-       struct intel_super *super = st->sb;
+       struct intel_super *super;

+       if (!st)
+               return;
+
+       super = st->sb;
        if (!super)
                return;

@@ -2721,7 +2778,6 @@ imsm_thunderdome(struct intel_super **super_list, int len)
  out:
        while (disk_list) {
                struct intel_disk *idisk = disk_list;
-
                disk_list = disk_list->next;
                free(idisk);
        }
@@ -3033,6 +3089,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
        dev = malloc(sizeof(*dev) + sizeof(__u32) * (info->raid_disks - 1));
        if (!dev) {
                free(dv);
+               dv = NULL;
                fprintf(stderr, Name": could not allocate raid device\n");
                return 0;
        }
@@ -3128,7 +3185,7 @@ static int init_super_imsm(struct supertype *st, mdu_array_info_t *info,

        super = alloc_super(1);
        if (super && posix_memalign(&super->buf, 512, mpb_size) != 0) {
-               free(super);
+               if (super) free(super);
                super = NULL;
        }
        if (!super) {
@@ -3268,6 +3325,7 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
                fprintf(stderr,
                        Name ": failed to retrieve scsi serial, aborting\n");
                free(dd);
+               dd = NULL;
                abort();
        }

@@ -3356,7 +3414,7 @@ static int make_mpb_imsm_compatible(struct supertype *st, struct imsm_super *mpb
        __u32 sum;
        int i, bytes_to_copy, spares = 0;
        struct dl *d;
-
+
        /* Make sure that there is missing disk */
        if (super->missing == NULL)
          return -1;
@@ -3376,7 +3434,6 @@ static int make_mpb_imsm_compatible(struct supertype *st, struct imsm_super *mpb

        /* Iterate through the imsm devices */
        for (i = 0; i < mpb->num_raid_devs; i++) {
-
                struct imsm_dev *dev = __get_imsm_dev(mpb, i);
                imsm_copy_dev(dev, get_imsm_dev(super, i));

@@ -3430,7 +3487,6 @@ static int make_mpb_imsm_compatible(struct supertype *st, struct imsm_super *mpb
 static int is_mpb_imsm_compatible(struct supertype *st, struct imsm_super *mpb)
 {
     int i;
-
        /* Iterate through the imsm devices */
     for (i = 0; i < mpb->num_raid_devs; i++) {
                struct imsm_dev *dev;
@@ -3444,6 +3500,9 @@ static int is_mpb_imsm_compatible(struct supertype *st, struct imsm_super *mpb)
                        if (a->info.container_member == i)
                                break;
                }
+               if (a == NULL) {
+                       return 0;
+               }
                /* Get first map */
                map = get_imsm_map(dev, 0);
                if ((map->raid_level == 5) && (a->info.array.layout == ALGORITHM_PARITY_N))     {
@@ -3565,7 +3624,6 @@ static int write_super_imsm(struct supertype *st, int doclose)

        for (i = 0; i < mpb->num_raid_devs; i++) {
                struct imsm_dev *dev = __get_imsm_dev(mpb, i);
-
                imsm_copy_dev(dev, get_imsm_dev(super, i));
                mpb_size += sizeof_imsm_dev(dev, 0);
        }
@@ -3823,7 +3881,7 @@ static unsigned long long merge_extents(struct intel_super *super, int sum_exten
        unsigned long reserve;

        if (!e)
-               return 0;
+               return ~0ULL; /* error */

        /* coalesce and sort all extents. also, check to see if we need to
         * reserve space between member arrays
@@ -3865,6 +3923,7 @@ static unsigned long long merge_extents(struct intel_super *super, int sum_exten
                i++;
        } while (e[i-1].size);
        free(e);
+       e = NULL;

        if (maxsize == 0)
                return 0;
@@ -3872,17 +3931,18 @@ static unsigned long long merge_extents(struct intel_super *super, int sum_exten
        /* FIXME assumes volume at offset 0 is the first volume in a
         * container
         */
+
        if (start_extent > 0)
                reserve = IMSM_RESERVED_SECTORS; /* gap between raid regions */
        else
                reserve = 0;

        if (maxsize < reserve)
-               return 0;
+               return ~0ULL;

        super->create_offset = ~((__u32) 0);
        if (start + reserve > super->create_offset)
-               return 0; /* start overflows create_offset */
+               return ~0ULL; /* start overflows create_offset */
        super->create_offset = start + reserve;

        return maxsize - reserve;
@@ -3954,7 +4014,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
        struct dl *dl;
        unsigned long long pos = 0;
        unsigned long long maxsize;
-       struct extent *e;
+       struct extent *e = NULL;
        int i;

        /* We must have the container info already read in. */
@@ -3999,6 +4059,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
                        if (found)
                                dcnt++;
                        free(e);
+                       e = NULL;
                }
                if (dcnt < raiddisks) {
                        if (verbose)
@@ -4311,10 +4372,15 @@ static struct mdinfo *container_content_imsm(struct supertype *st)
         *  and create appropriate device mdinfo.
         */
        struct intel_super *super = st->sb;
-       struct imsm_super *mpb = super->anchor;
+       struct imsm_super *mpb = NULL;
        struct mdinfo *rest = NULL;
        int i;

+       if (super)
+               mpb = super->anchor;
+       else
+               return NULL;
+
        /* do not assemble arrays that might have bad blocks */
        if (imsm_bbm_log_size(super->anchor)) {
                fprintf(stderr, Name ": BBM log found in metadata. "
@@ -4385,7 +4451,6 @@ static struct mdinfo *container_content_imsm(struct supertype *st)
                                this->resync_start = MaxSector;
                        if (skip)
                                continue;
-
                        info_d = calloc(1, sizeof(*info_d));
                        if (!info_d) {
                                fprintf(stderr, Name ": failed to allocate disk"
@@ -4397,10 +4462,11 @@ static struct mdinfo *container_content_imsm(struct supertype *st)
                                        free(info_d);
                                        info_d = d;
                                }
-                               free(this);
+                               if (this) free(this);
                                this = rest;
                                break;
                        }
+                       memset(info_d, 0, sizeof(*info_d));
                        info_d->next = this->devs;
                        this->devs = info_d;

@@ -4605,14 +4671,34 @@ static void mark_missing(struct imsm_dev *dev, struct imsm_disk *disk, int idx)
  */
 static int imsm_set_array_state(struct active_array *a, int consistent)
 {
-       int inst = a->info.container_member;
-       struct intel_super *super = a->container->sb;
-       struct imsm_dev *dev = get_imsm_dev(super, inst);
-       struct imsm_map *map = get_imsm_map(dev, 0);
-       int failed = imsm_count_failed(super, dev);
-       __u8 map_state = imsm_check_degraded(super, dev, failed);
+       int inst = 0;
+       struct intel_super *super = NULL;
+       struct imsm_dev *dev;
+       struct imsm_map *map;
+       int failed;
+       __u8 map_state;
        __u32 blocks_per_unit;

+       if (!a)
+           return consistent;
+
+       if (a->container) {
+               super = a->container->sb;
+               if (!super)
+                   return consistent;
+       }
+       else
+           return consistent;
+
+       inst = a->info.container_member;
+       dev = get_imsm_dev(super, inst);
+
+       if (dev == NULL)
+               return consistent;
+
+       map = get_imsm_map(dev, 0);
+       failed = imsm_count_failed(super, dev);
+       map_state = imsm_check_degraded(super, dev, failed);
        /* before we activate this array handle any missing disks */
        if (consistent == 2 && super->missing) {
                struct dl *dl;
@@ -4688,13 +4774,27 @@ static int imsm_set_array_state(struct active_array *a, int consistent)
 static void imsm_set_disk(struct active_array *a, int n, int state)
 {
        int inst = a->info.container_member;
-       struct intel_super *super = a->container->sb;
-       struct imsm_dev *dev = get_imsm_dev(super, inst);
-       struct imsm_map *map = get_imsm_map(dev, 0);
+       struct intel_super *super = NULL;
+       struct imsm_dev *dev;
+       struct imsm_map *map;
        struct imsm_disk *disk;
        int failed;
        __u32 ord;
        __u8 map_state;
+
+       if (a->container) {
+               super = a->container->sb;
+               if (super == NULL)
+                       return;
+       }
+       else
+           return;
+
+       dev = get_imsm_dev(super, inst);
+       map = get_imsm_map(dev, 0);
+
+       if ((dev == NULL) || (map == NULL))
+               return;

        if (n > map->num_members)
                fprintf(stderr, "imsm: set_disk %d out of range 0..%d\n",
@@ -4702,7 +4802,7 @@ static void imsm_set_disk(struct active_array *a, int n, int state)

        if (n < 0)
                return;
-
+
        dprintf("imsm: set_disk %d:%x\n", n, state);

        ord = get_imsm_ord_tbl_ent(dev, n);
@@ -4891,6 +4991,7 @@ static struct dl *imsm_add_spare(struct intel_super *super, int slot,
                }

                free(ex);
+               ex = NULL;
                if (i < mpb->num_raid_devs) {
                        dprintf("%x:%x does not have %u to %u available\n",
                                dl->major, dl->minor, array_start, array_end);
@@ -4925,14 +5026,14 @@ static int imsm_takeover(struct active_array *a,
        if (info.array.level == a->curr_level)
        {
                /* no raid level was actually changed */
-               fprintf(stderr, "Takeover started but no raid level was changed!\n");;
+               fprintf(stderr, "Takeover started but no raid level was changed!\n");
                return 0;
        }

        /* Read sysfs devs */
        mdi = sysfs_read(-1, a->devnum, GET_DEVS|SKIP_GONE_DEVS);
        if (!mdi) {
-               fprintf(stderr, "Could not read sysfs!\n");;
+               fprintf(stderr, "Could not read sysfs!\n");
                return 0;
        }

@@ -4943,6 +5044,7 @@ static int imsm_takeover(struct active_array *a,
                mu->buf = malloc(len);
                if (mu->buf == NULL) {
                        free(mu);
+                       mu = NULL;
                        fprintf(stderr, "%s: failed to allocate update buffer\n",
                                        __func__);
                        return 0;
@@ -5032,20 +5134,31 @@ static struct mdinfo *imsm_activate_spare(struct active_array *a,
         * container.
         */

-       struct intel_super *super = a->container->sb;
+       struct intel_super *super = NULL;
        int inst = a->info.container_member;
-       struct imsm_dev *dev = get_imsm_dev(super, inst);
-       struct imsm_map *map = get_imsm_map(dev, 0);
+       struct imsm_dev *dev;
+       struct imsm_map *map;
        int failed = a->info.array.raid_disks;
        struct mdinfo *rv = NULL;
        struct mdinfo *d;
        struct mdinfo *di;
        struct metadata_update *mu;
-       struct dl *dl;
+       struct dl *dl = NULL;
        struct imsm_update_activate_spare *u;
        int num_spares = 0;
        int i;

+       if (a->container) {
+               super = a->container->sb;
+               if (super == NULL)
+                       return NULL;
+       }
+       else
+               return NULL;
+
+       dev = get_imsm_dev(super, inst);
+       map = get_imsm_map(dev, 0);
+
        for (d = a->info.devs ; d ; d = d->next) {
                if ((d->curr_state & DS_FAULTY) &&
                        d->state_fd >= 0)
@@ -5222,10 +5335,15 @@ static void imsm_process_update(struct supertype *st,
         *      present in all member arrays then also clear the SPARE_DISK
         *      flag
         */
-       struct intel_super *super = st->sb;
+       struct intel_super *super;
        struct imsm_super *mpb;
        enum imsm_update_type type = *(enum imsm_update_type *) update->buf;

+       if ((st == NULL) || (update == NULL)) {
+               return;
+       }
+
+       super = st->sb;
        /* update requires a larger buf but the allocation failed */
        if (super->next_len && !super->next_buf) {
                super->next_len = 0;
@@ -5234,7 +5352,7 @@ static void imsm_process_update(struct supertype *st,

        if (super->next_buf) {
                memcpy(super->next_buf, super->buf, super->len);
-               free(super->buf);
+               if (super->buf) free(super->buf);
                super->len = super->next_len;
                super->buf = super->next_buf;

@@ -5245,7 +5363,6 @@ static void imsm_process_update(struct supertype *st,
        mpb = super->anchor;

        switch (type) {
-
        case update_takeover: {
                struct imsm_update_takeover *u = (void *) update->buf;
                struct imsm_dev *dev = get_imsm_dev(super, u->array);
@@ -5261,7 +5378,7 @@ static void imsm_process_update(struct supertype *st,
                                d = array->info.devs;
                                break;
                        }
-
+
                if (!array) {
                        fprintf(stderr, "error: could not find any active array!\n");
                        return;
@@ -5309,19 +5426,22 @@ static void imsm_process_update(struct supertype *st,
                            dl->major = dl->minor = 0;
                            dl->fd = -1;
                            dl->devname = strdup("missing");
-                               dl->index = mpb->num_disks;
+                           dl->index = mpb->num_disks;
                            sprintf((char*)dl->disk.serial, "MISSING_DISK%d", i);
                            dl->disk.total_blocks = -1;
                            dl->disk.scsi_id = -1;
                            dl->disk.status = FAILED_DISK;
                            dl->disk.owner_cfg_num = 0;
                            dl->e = NULL;
-                           dl->next = super->missing;
+                           dl->next = super->missing;
                            super->missing = dl;
+
                            /* Set slot for missing disk */
                            slot = find_free_slot(d, slot);
+
                            set_imsm_ord_tbl_ent(map, slot, dl->index | IMSM_ORD_REBUILD);
-                           dl->raiddisk = slot;
+                           dl->raiddisk = slot;
+
                            /* Increase number of disks */
                            mpb->num_disks++;
                        }
@@ -5331,48 +5451,50 @@ static void imsm_process_update(struct supertype *st,
                        map->failed_disk_num = dl->index;
                        map->map_state = IMSM_T_STATE_DEGRADED;
                }
-
                if (u->delta_disks < 0)
                {
                        /* we'll be adding missing disks: Raid5->Raid0 or Raid10->Raid0 */
                        int missing_disks = 0;
+
                        dl = super->missing;
-
+
                        /* Count missing drives */
                        while(dl) {
                                missing_disks--;
                                dl = dl->next;
                        }
-                   if (missing_disks != (u->delta_disks)) {
-                       fprintf(stderr, "error: incorrect missing drive number for takeover: %d\n",
-                                               missing_disks);
-                       break;
-                   }
-                   /* removing missing disk */
-                   while (super->missing) {
+                       if (missing_disks != (u->delta_disks)) {
+                           fprintf(stderr, "error: incorrect missing drive number for takeover: %d\n",
+                                                   missing_disks);
+                           break;
+                       }
+
+                       while (super->missing) {
                                dl = super->missing;
                                super->missing = dl->next;
                                __free_imsm_disk(dl);
-                   }
-                   /* Update slots in the raid map */
-                   for (i = 0; i < u->sl_changed; i++) {
+                       }
+
+                       /* Update slots in the raid map */
+                       for (i = 0; i < u->sl_changed; i++) {
                                int idx;
                                idx = get_imsm_ord_tbl_ent(dev, u->sl_changes[i].prev_slot);
                                /* now after slot changes */
                                set_imsm_ord_tbl_ent(map, u->sl_changes[i].new_slot, idx);
                        }
-                   /* Update mpb */
-                   mpb->num_disks += u->delta_disks;
-                   map->num_members += u->delta_disks;
-                   map->failed_disk_num = 0;
-                   map->map_state = IMSM_T_STATE_NORMAL;
+
+                       /* Update mpb */
+                       mpb->num_disks += u->delta_disks;
+                       map->num_members += u->delta_disks;
+                       map->failed_disk_num = 0;
+                       map->map_state = IMSM_T_STATE_NORMAL;
                }
-
+
                /* Update raid level */
                map->raid_level = u->new_level;
                super->updates_pending++;
                array->takeover = finished;
-
+
                imsm_update_version_info(super);
                break;
        }
@@ -5583,7 +5705,14 @@ static void imsm_process_update(struct supertype *st,
                 */
                if (update->space) {
                        dv = update->space;
-                       free(dv->dev);
+                       if (dv)
+                       {
+                               if (dv->dev)
+                               {
+                                       free(dv->dev);
+                                       dv->dev = NULL;
+                               }
+                       }
                }
                break;
        }
@@ -5624,25 +5753,35 @@ static void imsm_prepare_update(struct supertype *st,
         * integrated by the monitor thread without worrying about live pointers
         * in the manager thread.
         */
-       enum imsm_update_type type = *(enum imsm_update_type *) update->buf;
-       struct intel_super *super = st->sb;
-       struct imsm_super *mpb = super->anchor;
+       enum imsm_update_type type;
+       struct intel_super *super;
+       struct imsm_super *mpb;
        size_t buf_len;
        size_t len = 0;

-       switch (type) {
+       if (update)
+               type = *(enum imsm_update_type *) update->buf;
+       else return;

+       if (st)
+               super = st->sb;
+       else return;
+
+       if (super)
+               mpb = super->anchor;
+       else return;
+
+       switch (type) {
        case update_takeover: {
                struct imsm_update_takeover *u = (void *) update->buf;
                struct imsm_dev *dev = get_imsm_dev(super, u->array);
-
                /* calculate the new size for imsm dev */
                len = sizeof_imsm_dev(dev, 1);
                if (u->delta_disks > 0)
                        len += u->delta_disks * sizeof(struct imsm_disk);

                update->space = NULL;
-               break;
+               break;
        }

        case update_create_array: {
@@ -5665,6 +5804,7 @@ static void imsm_prepare_update(struct supertype *st,
                                update->space = dv;
                        else {
                                free(dv);
+                               dv = NULL;
                                update->space = NULL;
                        }
                }
diff --git a/sysfs.c b/sysfs.c
index ebf9d8a..cb57bff 100644
--- a/sysfs.c
+++ b/sysfs.c
@@ -51,6 +51,7 @@ void sysfs_free(struct mdinfo *sra)
                        struct mdinfo *d = sra->devs;
                        sra->devs = d->next;
                        free(d);
+                       d = NULL;
                }
                free(sra);
                sra = sra2;
@@ -104,8 +105,8 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
        char buf[PATH_MAX];
        char *base;
        char *dbase;
-       struct mdinfo *sra;
-       struct mdinfo *dev;
+       struct mdinfo *sra = NULL;
+       struct mdinfo *dev = NULL;
        DIR *dir = NULL;
        struct dirent *de;

@@ -123,6 +124,7 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
        base = fname + strlen(fname);

        sra->devs = NULL;
+       sra->next = NULL;
        if (options & GET_VERSION) {
                strcpy(base, "metadata_version");
                if (load_sys(fname, buf))
@@ -134,12 +136,12 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
                } else if (strncmp(buf, "external:", 9) == 0) {
                        sra->array.major_version = -1;
                        sra->array.minor_version = -2;
-                       strcpy(sra->text_version, buf+9);
+                       strncpy(sra->text_version, buf+9, 50);
                } else {
                        sscanf(buf, "%d.%d",
                               &sra->array.major_version,
                               &sra->array.minor_version);
-                       strcpy(sra->text_version, buf);
+                       strncpy(sra->text_version, buf, 50);
                }
        }
        if (options & GET_LEVEL) {
@@ -244,7 +246,8 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
                dev = malloc(sizeof(*dev));
                if (!dev)
                        goto abort;
-
+               memset(dev, 0, sizeof(*dev));
+
                /* Always get slot, major, minor */
                strcpy(dbase, "slot");
                if (load_sys(fname, buf)) {
@@ -256,6 +259,7 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
                            errno != ENAMETOOLONG) {
                                /* ...yup device is gone */
                                free(dev);
+                               dev = NULL;
                                continue;
                        } else {
                                /* slot is unreadable but 'block' link
@@ -263,6 +267,7 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
                                 * so abort
                                 */
                                free(dev);
+                               dev = NULL;
                                goto abort;
                        }

@@ -274,6 +279,7 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
                strcpy(dbase, "block/dev");
                if (load_sys(fname, buf)) {
                        free(dev);
+                       dev = NULL;
                        if (options & SKIP_GONE_DEVS)
                                continue;
                        else
@@ -287,6 +293,7 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
                        if (load_sys(fname, buf) == 0 &&
                            strncmp(buf, "offline", 7) == 0) {
                                free(dev);
+                               dev = NULL;
                                continue;
                        }
                }
@@ -394,7 +401,7 @@ unsigned long long get_component_size(int fd)
 int sysfs_set_str(struct mdinfo *sra, struct mdinfo *dev,
                  char *name, char *val)
 {
-       char fname[50];
+       char fname[60];
        int n;
        int fd;

@@ -440,7 +447,7 @@ int sysfs_uevent(struct mdinfo *sra, char *event)
 int sysfs_get_fd(struct mdinfo *sra, struct mdinfo *dev,
                       char *name)
 {
-       char fname[50];
+       char fname[60];
        int fd;

        sprintf(fname, "/sys/block/%s/md/%s/%s",
@@ -586,9 +593,12 @@ int sysfs_add_disk(struct mdinfo *sra, struct mdinfo *sd, int resume)
                return -1;
        nm[rv] = '\0';
        dname = strrchr(nm, '/');
-       if (dname) dname++;
-       strcpy(sd->sys_name, "dev-");
-       strcpy(sd->sys_name+4, dname);
+       if (dname) {
+               dname++;
+               strcpy(sd->sys_name, "dev-");
+               strcpy(sd->sys_name+4, dname);
+       }
+       else return -1;

        /* test write to see if 'recovery_start' is available */
        if (resume && sd->recovery_start < MaxSector &&
@@ -712,18 +722,24 @@ int sysfs_disk_to_scsi_id(int fd, __u32 *id)
        c1 = strchr(de->d_name, ':');
        c1++;
        c2 = strchr(c1, ':');
-       *c2 = '\0';
-       *id = strtol(c1, NULL, 10) << 24; /* host */
-       c1 = c2 + 1;
-       c2 = strchr(c1, ':');
-       *c2 = '\0';
-       *id |= strtol(c1, NULL, 10) << 16; /* channel */
-       c1 = c2 + 1;
-       c2 = strchr(c1, ':');
-       *c2 = '\0';
-       *id |= strtol(c1, NULL, 10) << 8; /* lun */
-       c1 = c2 + 1;
-       *id |= strtol(c1, NULL, 10); /* id */
+       if (c2) {
+               *c2 = '\0';
+               *id = strtol(c1, NULL, 10) << 24; /* host */
+               c1 = c2 + 1;
+               c2 = strchr(c1, ':');
+               if (c2) {
+                       *c2 = '\0';
+                       *id |= strtol(c1, NULL, 10) << 16; /* channel */
+                       c1 = c2 + 1;
+                       c2 = strchr(c1, ':');
+                       if (c2) {
+                               *c2 = '\0';
+                               *id |= strtol(c1, NULL, 10) << 8; /* lun */
+                               c1 = c2 + 1;
+                               *id |= strtol(c1, NULL, 10); /* id */
+                       }
+               }
+       }

        return 0;
 }
diff --git a/util.c b/util.c
index 5feec43..ea74efe 100644
--- a/util.c
+++ b/util.c
@@ -244,12 +244,16 @@ int parse_layout_faulty(char *layout)
        int ln = strcspn(layout, "0123456789");
        char *m = strdup(layout);
        int mode;
-       m[ln] = 0;
-       mode = map_name(faultylayout, m);
-       if (mode == UnSet)
-               return -1;
+
+       if (m) {
+               m[ln] = 0;
+               mode = map_name(faultylayout, m);
+               if (mode == UnSet)
+                       return -1;

-       return mode | (atoi(layout+ln)<< ModeShift);
+               return mode | (atoi(layout+ln)<< ModeShift);
+       } else
+               return -1;
 }
 #endif

@@ -579,15 +583,19 @@ int add_dev(const char *name, const struct stat *stb, int flag, struct FTW *s)

        if ((stb->st_mode&S_IFMT)== S_IFBLK) {
                char *n = strdup(name);
-               struct devmap *dm = malloc(sizeof(*dm));
-               if (strncmp(n, "/dev/./", 7)==0)
-                       strcpy(n+4, name+6);
-               if (dm) {
-                       dm->major = major(stb->st_rdev);
-                       dm->minor = minor(stb->st_rdev);
-                       dm->name = n;
-                       dm->next = devlist;
-                       devlist = dm;
+               struct devmap *dm = NULL;
+
+               if (n != NULL) {
+                       dm = malloc(sizeof(*dm));
+                       if (strncmp(n, "/dev/./", 7)==0)
+                               strcpy(n+4, name+6);
+                       if (dm) {
+                               dm->major = major(stb->st_rdev);
+                               dm->minor = minor(stb->st_rdev);
+                               dm->name = n;
+                               dm->next = devlist;
+                               devlist = dm;
+                       }
                }
        }
        return 0;
@@ -633,8 +641,12 @@ char *map_dev(int major, int minor, int create)
                while(devlist) {
                        struct devmap *d = devlist;
                        devlist = d->next;
-                       free(d->name);
+                       if (d->name) {
+                               free(d->name);
+                               d->name = NULL;
+                       }
                        free(d);
+                       d = NULL;
                }
                if (lstat(dev, &stb)==0 &&
                    S_ISLNK(stb.st_mode))
@@ -803,6 +815,7 @@ static int mdp_major = -1;
                if (have_devices && strcmp(w, "mdp")==0)
                        mdp_major = last_num;
                free(w);
+               w = NULL;
        }
        fclose(fl);
        return mdp_major;
@@ -917,7 +930,7 @@ int dev_open(char *dev, int flags)

 int open_dev(int devnum)
 {
-       char buf[20];
+       char buf[30];

        sprintf(buf, "%d:%d", dev2major(devnum), dev2minor(devnum));
        return dev_open(buf, O_RDWR);
@@ -925,7 +938,7 @@ int open_dev(int devnum)

 int open_dev_excl(int devnum)
 {
-       char buf[20];
+       char buf[30];
        int i;

        sprintf(buf, "%d:%d", dev2major(devnum), dev2minor(devnum));
@@ -987,7 +1000,7 @@ struct supertype *super_by_fd(int fd)
        struct supertype *st = NULL;
        struct mdinfo *sra;
        char *verstr;
-       char version[20];
+       char version[30];
        int i;
        char *subarray = NULL;

@@ -1016,7 +1029,8 @@ struct supertype *super_by_fd(int fd)
                if (subarray)
                        *subarray++ = '\0';
                devnum = devname2devnum(dev);
-               subarray = strdup(subarray);
+               if (subarray)
+                       subarray = strdup(subarray);
                if (sra)
                        sysfs_free(sra);
                sra = sysfs_read(-1, devnum, GET_VERSION);
@@ -1030,13 +1044,17 @@ struct supertype *super_by_fd(int fd)
                st = superlist[i]->match_metadata_desc(verstr);

        if (sra)
+       {
                sysfs_free(sra);
+               sra = NULL;
+       }
        if (st) {
                st->sb = NULL;
                if (subarray) {
                        strncpy(st->subarray, subarray, 32);
                        st->subarray[31] = 0;
                        free(subarray);
+                       subarray = NULL;
                } else
                        st->subarray[0] = 0;
        }
@@ -1076,32 +1094,35 @@ struct supertype *guess_super(int fd)
        int i;

        st = malloc(sizeof(*st));
-       for (i=0 ; superlist[i]; i++) {
-               int rv;
-               ss = superlist[i];
-               memset(st, 0, sizeof(*st));
-               rv = ss->load_super(st, fd, NULL);
-               if (rv == 0) {
-                       struct mdinfo info;
-                       st->ss->getinfo_super(st, &info);
-                       if (bestsuper == -1 ||
-                           besttime < info.array.ctime) {
-                               bestsuper = i;
-                               besttime = info.array.ctime;
+       if (st)
+       {
+               for (i=0 ; superlist[i]; i++) {
+                       int rv;
+                       ss = superlist[i];
+                       memset(st, 0, sizeof(*st));
+                       rv = ss->load_super(st, fd, NULL);
+                       if (rv == 0) {
+                               struct mdinfo info;
+                               st->ss->getinfo_super(st, &info);
+                               if (bestsuper == -1 ||
+                                   besttime < info.array.ctime) {
+                                       bestsuper = i;
+                                       besttime = info.array.ctime;
+                               }
+                               ss->free_super(st);
                        }
-                       ss->free_super(st);
                }
-       }
-       if (bestsuper != -1) {
-               int rv;
-               memset(st, 0, sizeof(*st));
-               rv = superlist[bestsuper]->load_super(st, fd, NULL);
-               if (rv == 0) {
-                       superlist[bestsuper]->free_super(st);
-                       return st;
+               if (bestsuper != -1) {
+                       int rv;
+                       memset(st, 0, sizeof(*st));
+                       rv = superlist[bestsuper]->load_super(st, fd, NULL);
+                       if (rv == 0) {
+                               superlist[bestsuper]->free_super(st);
+                               return st;
+                       }
                }
+               free(st);
        }
-       free(st);
        return NULL;
 }

@@ -1337,7 +1358,7 @@ int add_disk(int mdfd, struct supertype *st,
        /* Add a device to an array, in one of 2 ways. */
        int rv;
 #ifndef MDASSEMBLE
-       if (st->ss->external) {
+       if ((st!=NULL) && (st->ss->external)) {
                if (info->disk.state & (1<<MD_DISK_SYNC))
                        info->recovery_start = MaxSector;
                else
@@ -1350,9 +1371,11 @@ int add_disk(int mdfd, struct supertype *st,
                                        break;
                        if (sd2 == NULL) {
                                sd2 = malloc(sizeof(*sd2));
-                               *sd2 = *info;
-                               sd2->next = sra->devs;
-                               sra->devs = sd2;
+                               if (sd2 != NULL) {
+                                       *sd2 = *info;
+                                       sd2->next = sra->devs;
+                                       sra->devs = sd2;
+                               }
                        }
                }
        } else
@@ -1404,10 +1427,10 @@ unsigned long long min_recovery_start(struct mdinfo *array)
 char *devnum2devname(int num)
 {
        char name[100];
-       if (num >= 0)
-               sprintf(name, "md%d", num);
+       if (num > 0)
+               snprintf(name, 100, "md%d", num);
        else
-               sprintf(name, "md_d%d", -1-num);
+               snprintf(name, 100, "md_d%d", -1-num);
        return strdup(name);
 }

@@ -1424,11 +1447,12 @@ int devname2devnum(char *name)

 int stat2devnum(struct stat *st)
 {
-       char path[30];
+       char path[50];
        char link[200];
        char *cp;
        int n;

+    if (st)
        if ((S_IFMT & st->st_mode) == S_IFBLK) {
                if (major(st->st_rdev) == MD_MAJOR)
                        return minor(st->st_rdev);
@@ -1580,11 +1604,20 @@ __u32 random32(void)
 int flush_metadata_updates(struct supertype *st)
 {
        int sfd;
+
+       if (!st) {
+               return -1;
+       }
+
        if (!st->updates) {
                st->update_tail = NULL;
                return -1;
        }

+       if (!st->container_dev) {
+               return -1;
+       }
+
        sfd = connect_monitor(devnum2devname(st->container_dev));
        if (sfd < 0)
                return -1;
@@ -1595,8 +1628,14 @@ int flush_metadata_updates(struct supertype *st)

                send_message(sfd, mu, 0);
                wait_reply(sfd, 0);
-               free(mu->buf);
-               free(mu);
+               if (mu->buf) {
+                       free(mu->buf);
+                       mu->buf = NULL;
+               }
+               if (mu) {
+                       free(mu);
+                       mu = NULL;
+               }
        }
        ack(sfd, 0);
        wait_reply(sfd, 0);
@@ -1610,12 +1649,14 @@ void append_metadata_update(struct supertype *st, void *buf, int len)

        struct metadata_update *mu = malloc(sizeof(*mu));

-       mu->buf = buf;
-       mu->len = len;
-       mu->space = NULL;
-       mu->next = NULL;
-       *st->update_tail = mu;
-       st->update_tail = &mu->next;
+       if (mu) {
+               mu->buf = buf;
+               mu->len = len;
+               mu->space = NULL;
+               mu->next = NULL;
+               *st->update_tail = mu;
+               st->update_tail = &mu->next;
+       }
 }
 #endif /* MDASSEMBLE */

--
1.6.0.2

--
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