]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
mdadm/Grow: fix coverity issue RESOURCE_LEAK
authorXiao Ni <xni@redhat.com>
Fri, 26 Jul 2024 07:14:04 +0000 (15:14 +0800)
committerMariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Mon, 5 Aug 2024 09:07:23 +0000 (11:07 +0200)
Fix some resource leak problems.

Signed-off-by: Xiao Ni <xni@redhat.com>
Signed-off-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Grow.c

diff --git a/Grow.c b/Grow.c
index 7ae967bda06726d856d6c0f6478f181811bcbe7a..907a6e1b9e22f313ce614f4b49c25a0be6b44b64 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -530,8 +530,10 @@ int Grow_addbitmap(char *devname, int fd, struct context *c, struct shape *s)
                                pr_err("Cannot add bitmap while array is resyncing or reshaping etc.\n");
                        pr_err("Cannot set bitmap file for %s: %s\n",
                                devname, strerror(err));
+                       close_fd(&bitmap_fd);
                        return 1;
                }
+               close_fd(&bitmap_fd);
        }
 
        return 0;
@@ -3083,6 +3085,7 @@ static int reshape_array(char *container, int fd, char *devname,
        int done;
        struct mdinfo *sra = NULL;
        char buf[SYSFS_MAX_BUF_SIZE];
+       bool located_backup = false;
 
        /* when reshaping a RAID0, the component_size might be zero.
         * So try to fix that up.
@@ -3165,8 +3168,10 @@ static int reshape_array(char *container, int fd, char *devname,
                        goto release;
                }
 
-               if (!backup_file)
+               if (!backup_file) {
                        backup_file = locate_backup(sra->sys_name);
+                       located_backup = true;
+               }
 
                goto started;
        }
@@ -3612,15 +3617,13 @@ started:
                        mdstat_wait(30 - (delayed-1) * 25);
        } while (delayed);
        mdstat_close();
-       if (check_env("MDADM_GROW_VERIFY"))
-               fd = open(devname, O_RDONLY | O_DIRECT);
-       else
-               fd = -1;
        mlockall(MCL_FUTURE);
 
        if (signal_s(SIGTERM, catch_term) == SIG_ERR)
                goto release;
 
+       if (check_env("MDADM_GROW_VERIFY"))
+               fd = open(devname, O_RDONLY | O_DIRECT);
        if (st->ss->external) {
                /* metadata handler takes it from here */
                done = st->ss->manage_reshape(
@@ -3632,6 +3635,7 @@ started:
                        fd, sra, &reshape, st, blocks, fdlist, offsets,
                        d - odisks, fdlist + odisks, offsets + odisks);
 
+       close_fd(&fd);
        free(fdlist);
        free(offsets);
 
@@ -3701,6 +3705,8 @@ out:
        exit(0);
 
 release:
+       if (located_backup)
+               free(backup_file);
        free(fdlist);
        free(offsets);
        if (orig_level != UnSet && sra) {
@@ -3839,6 +3845,7 @@ int reshape_container(char *container, char *devname,
                        pr_err("Unable to initialize sysfs for %s\n",
                               mdstat->devnm);
                        rv = 1;
+                       close_fd(&fd);
                        break;
                }
 
@@ -4717,6 +4724,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist,
        unsigned long long *offsets;
        unsigned long long  nstripe, ostripe;
        int ndata, odata;
+       int fd, backup_fd = -1;
 
        odata = info->array.raid_disks - info->delta_disks - 1;
        if (info->array.level == 6)
@@ -4732,9 +4740,18 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist,
                 * been used
                 */
                old_disks = cnt;
+
+       if (backup_file) {
+               backup_fd = open(backup_file, O_RDONLY);
+               if (!is_fd_valid(backup_fd)) {
+                       pr_err("Can't open backup file %s : %s\n",
+                               backup_file, strerror(errno));
+                       return -EINVAL;
+               }
+       }
+
        for (i=old_disks-(backup_file?1:0); i<cnt; i++) {
                struct mdinfo dinfo;
-               int fd;
                int bsbsize;
                char *devname, namebuf[20];
                unsigned long long lo, hi;
@@ -4747,12 +4764,9 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist,
                 * else restore data and update all superblocks
                 */
                if (i == old_disks-1) {
-                       fd = open(backup_file, O_RDONLY);
-                       if (fd<0) {
-                               pr_err("backup file %s inaccessible: %s\n",
-                                       backup_file, strerror(errno));
+                       if (!is_fd_valid(backup_fd))
                                continue;
-                       }
+                       fd = backup_fd;
                        devname = backup_file;
                } else {
                        fd = fdlist[i];
@@ -4907,6 +4921,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist,
                                pr_err("Error restoring backup from %s\n",
                                        devname);
                        free(offsets);
+                       close_fd(&backup_fd);
                        return 1;
                }
 
@@ -4923,6 +4938,7 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist,
                                pr_err("Error restoring second backup from %s\n",
                                        devname);
                        free(offsets);
+                       close_fd(&backup_fd);
                        return 1;
                }
 
@@ -4984,8 +5000,12 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist,
                        st->ss->store_super(st, fdlist[j]);
                        st->ss->free_super(st);
                }
+               close_fd(&backup_fd);
                return 0;
        }
+
+       close_fd(&backup_fd);
+
        /* Didn't find any backup data, try to see if any
         * was needed.
         */