On Mon, Nov 02, 2020 at 10:41:22AM +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 mpvec is NULL, > we free newmp at the end of the func. > > Signed-off-by: Lixiaokeng <lixiaokeng@xxxxxxxxxx> > Signed-off-by: Zhiqiang Liu <liuzhiqiang26@xxxxxxxxxx> > Signed-off-by: Linfeilong <linfeilong@xxxxxxxxxx> > --- > libmultipath/configure.c | 40 +++++++++++++++++++++++++++++----------- > 1 file changed, 29 insertions(+), 11 deletions(-) > > diff --git a/libmultipath/configure.c b/libmultipath/configure.c > index 6fb477fc..649002c3 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,10 +1144,20 @@ 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; > > + if (mpvec) > + newmp = mpvec; > + else > + newmp = vector_alloc(); > + if (!newmp) { > + condlog(0, "can not allocate newmp"); > + return ret; > + } > + It's possible that this patch is based on different code than I am looking at, but otherwise, You should either move this code below the code that checks the pathvec size and allocates the bitfield, or make the failure path for that code free newmp, if necessary. Otherwise, you could leak newmp on those failures. -Ben > /* ignore refwwid if it's empty */ > if (refwwid && !strlen(refwwid)) > refwwid = NULL; > @@ -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; > } -- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel