]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Fix memory leak in file Manage
authorGuanqin Miao <miaoguanqin@huawei.com>
Mon, 24 Apr 2023 08:06:36 +0000 (16:06 +0800)
committerJes Sorensen <jes@trained-monkey.org>
Fri, 1 Sep 2023 16:08:06 +0000 (12:08 -0400)
When we test mdadm with asan, we found some memory leaks in Manage.c
We fix these memory leaks based on code logic.

v2: Fix free() of uninitialized 'tst' in abort path.

Signed-off-by: Guanqin Miao <miaoguanqin@huawei.com>
Signed-off-by: Li Xiao Keng <lixiaokeng@huawei.com>
Acked-by: Mariusz Tkaczyk <mariusz.tkaczyk@linux.intel.com>
Signed-off-by: Jes Sorensen <jes@trained-monkey.org>
Manage.c

index f54de7c685ef76425eaa86896cb254cd15fec2bf..f997b1633e74bcdf32dcb763b851ab4c3badc6de 100644 (file)
--- a/Manage.c
+++ b/Manage.c
@@ -222,6 +222,7 @@ int Manage_stop(char *devname, int fd, int verbose, int will_retry)
                if (verbose >= 0)
                        pr_err("Cannot get exclusive access to %s:Perhaps a running process, mounted filesystem or active volume group?\n",
                               devname);
+               sysfs_free(mdi);
                return 1;
        }
        /* If this is an mdmon managed array, just write 'inactive'
@@ -801,8 +802,14 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
                                                    rdev, update, devname,
                                                    verbose, array);
                                dev_st->ss->free_super(dev_st);
-                               if (rv)
+                               if (rv) {
+                                       free(dev_st);
                                        return rv;
+                               }
+                       }
+                       if (dev_st) {
+                               dev_st->ss->free_super(dev_st);
+                               free(dev_st);
                        }
                }
                if (dv->disposition == 'M') {
@@ -1362,7 +1369,7 @@ int Manage_subdevs(char *devname, int fd,
        unsigned long long array_size;
        struct mddev_dev *dv;
        int tfd = -1;
-       struct supertype *tst;
+       struct supertype *tst = NULL;
        char *subarray = NULL;
        int sysfd = -1;
        int count = 0; /* number of actions taken */
@@ -1699,6 +1706,7 @@ int Manage_subdevs(char *devname, int fd,
                        break;
                }
        }
+       free(tst);
        if (frozen > 0)
                sysfs_set_str(&info, NULL, "sync_action","idle");
        if (test && count == 0)
@@ -1706,6 +1714,7 @@ int Manage_subdevs(char *devname, int fd,
        return 0;
 
 abort:
+       free(tst);
        if (frozen > 0)
                sysfs_set_str(&info, NULL, "sync_action","idle");
        return !test && busy ? 2 : 1;