[dm-devel] [PATCH v4] libmultipath: fix memory leaks in coalesce_paths
Benjamin Marzinski
bmarzins at redhat.com
Mon Nov 9 19:59:41 UTC 2020
On Mon, Nov 09, 2020 at 12:32:05PM +0800, lixiaokeng wrote:
> When multipath -F are executed first and multipath -v2 or
> -d are executed later, asan will warn memory leaks. The
> reason is that the mpp allocated in coalesce_paths isn't
> freed. Here we use newmp to store mpp. If newmp need not
> be copied to mpvec, we free newmp at the end of the func.
>
Reviewed-by: Benjamin Marzinski <bmarzins at redhat.com>
> Signed-off-by: Lixiaokeng <lixiaokeng at huawei.com>
> Signed-off-by: Zhiqiang Liu <liuzhiqiang26 at huawei.com>
> Signed-off-by: Linfeilong <linfeilong at huawei.com>
> ---
> libmultipath/configure.c | 40 +++++++++++++++++++++++++++++-----------
> 1 file changed, 29 insertions(+), 11 deletions(-)
>
> diff --git a/libmultipath/configure.c b/libmultipath/configure.c
> index 6fb477fc..2547e1d5 100644
> --- a/libmultipath/configure.c
> +++ b/libmultipath/configure.c
> @@ -1132,7 +1132,7 @@ out:
> * FORCE_RELOAD_WEAK: existing maps are compared to the current conf and only
> * reloaded in DM if there's a difference. This is useful during startup.
> */
> -int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
> +int coalesce_paths (struct vectors *vecs, vector mpvec, char *refwwid,
> int force_reload, enum mpath_cmds cmd)
> {
> int ret = CP_FAIL;
> @@ -1144,6 +1144,7 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
> struct path * pp2;
> vector curmp = vecs->mpvec;
> vector pathvec = vecs->pathvec;
> + vector newmp;
> struct config *conf;
> int allow_queueing;
> struct bitfield *size_mismatch_seen;
> @@ -1164,6 +1165,15 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
> if (size_mismatch_seen == NULL)
> return CP_FAIL;
>
> + if (mpvec)
> + newmp = mpvec;
> + else
> + newmp = vector_alloc();
> + if (!newmp) {
> + condlog(0, "can not allocate newmp");
> + goto out;
> + }
> +
> vector_foreach_slot (pathvec, pp1, k) {
> int invalid;
> /* skip this path for some reason */
> @@ -1270,8 +1280,14 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
> goto out;
> }
> }
> - if (r == DOMAP_DRY)
> + if (r == DOMAP_DRY) {
> + if (!vector_alloc_slot(newmp)) {
> + remove_map(mpp, vecs->pathvec, vecs->mpvec, KEEP_VEC);
> + goto out;
> + }
> + vector_set_slot(newmp, mpp);
> continue;
> + }
>
> if (r == DOMAP_EXIST && mpp->action == ACT_NOTHING &&
> force_reload == FORCE_RELOAD_WEAK)
> @@ -1307,22 +1323,22 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
> print_multipath_topology(mpp, verbosity);
> }
>
> - if (newmp) {
> - if (mpp->action != ACT_REJECT) {
> - if (!vector_alloc_slot(newmp))
> - goto out;
> - vector_set_slot(newmp, mpp);
> + if (mpp->action != ACT_REJECT) {
> + if (!vector_alloc_slot(newmp)) {
> + remove_map(mpp, vecs->pathvec, vecs->mpvec, KEEP_VEC);
> + goto out;
> }
> - else
> - remove_map(mpp, vecs->pathvec, vecs->mpvec,
> - KEEP_VEC);
> + vector_set_slot(newmp, mpp);
> }
> + else
> + remove_map(mpp, vecs->pathvec, vecs->mpvec,
> + KEEP_VEC);
> }
> /*
> * Flush maps with only dead paths (ie not in sysfs)
> * Keep maps with only failed paths
> */
> - if (newmp) {
> + if (mpvec) {
> vector_foreach_slot (newmp, mpp, i) {
> char alias[WWID_SIZE];
>
> @@ -1345,6 +1361,8 @@ int coalesce_paths (struct vectors * vecs, vector newmp, char * refwwid,
> ret = CP_OK;
> out:
> free(size_mismatch_seen);
> + if (!mpvec)
> + free_multipathvec(newmp, KEEP_PATHS);
> return ret;
> }
>
> --
More information about the dm-devel
mailing list