From mboxrd@z Thu Jan 1 00:00:00 1970 From: David Teigland Date: Mon, 12 Jul 2021 19:24:18 +0000 (GMT) Subject: main - toolcontext: fix double free (core dumped) issue Message-ID: <20210712192418.2BE5D381DC1F@sourceware.org> List-Id: To: lvm-devel@redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=db22a389cfb12eef77dfc2e1ce124ac83ed6c5a2 Commit: db22a389cfb12eef77dfc2e1ce124ac83ed6c5a2 Parent: 66daedc6d27d07e4bcd43ee0286e21a69fdc33d9 Author: Heming Zhao AuthorDate: Tue Jul 13 03:01:00 2021 +0800 Committer: David Teigland CommitterDate: Mon Jul 12 14:10:21 2021 -0500 toolcontext: fix double free (core dumped) issue How to trigger: ``` ~ # export LVM_SYSTEM_DIR=_ ~ # pvscan No matching physical volumes found double free or corruption (!prev) Aborted (core dumped) ``` when LVM_SYSTEM_DIR is empty, _load_config_file() won't be called. when LVM_SYSTEM_DIR is not empty, cfl->cft links into cmd->config_files by _load_config_file()@lib/commands/toolcontext.c core dumped code: _destroy_config()@lib/commands/toolcontext.c ``` /* CONFIG_FILE/CONFIG_MERGED_FILES */ if ((cft = remove_config_tree_by_source(cmd, CONFIG_MERGED_FILES))) config_destroy(cft); else if ((cft = remove_config_tree_by_source(cmd, CONFIG_FILE))) config_destroy(cft); <=== first free the cft dm_list_iterate_items(cfl, &cmd->config_files) config_destroy(cfl->cft); <=== double free the cft ``` Fixes: c43f2f8ae08ed0555a300764c8644ea56f4f41e2 Signed-off-by: Heming Zhao --- lib/commands/toolcontext.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c index b295a20ef..742bdd9c2 100644 --- a/lib/commands/toolcontext.c +++ b/lib/commands/toolcontext.c @@ -966,8 +966,13 @@ static void _destroy_config(struct cmd_context *cmd) /* CONFIG_FILE/CONFIG_MERGED_FILES */ if ((cft = remove_config_tree_by_source(cmd, CONFIG_MERGED_FILES))) config_destroy(cft); - else if ((cft = remove_config_tree_by_source(cmd, CONFIG_FILE))) + else if ((cft = remove_config_tree_by_source(cmd, CONFIG_FILE))) { + dm_list_iterate_items(cfl, &cmd->config_files) { + if (cfl->cft == cft) + dm_list_del(&cfl->list); + } config_destroy(cft); + } dm_list_iterate_items(cfl, &cmd->config_files) config_destroy(cfl->cft);