Skip to content

Commit 94f719e

Browse files
committed
optparse: fix segfault on optparse_reg_subcommand() failure
Problem: When an error in a subcommand definition causes the registration of the subcommand to fail, liboptparse crashes due to a double free. This issue occurs whenever an optparse subcommand object is freed before its parent. When the subcommand is unlinked from the parent in optparse_destroy(), the zhash free function is called, which ends up calling optparse_destroy() again. If p->parent != NULL in optparse_destroy(), then the function is being called directly on a child. After the call to zhash_delete(), return immediately and let the destructor finish the rest of the cleanup. Fixes #5731
1 parent ca942ab commit 94f719e

File tree

1 file changed

+12
-1
lines changed

1 file changed

+12
-1
lines changed

src/common/liboptparse/optparse.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -697,8 +697,19 @@ void optparse_destroy (optparse_t *p)
697697
return;
698698

699699
/* Unlink from parent */
700-
if (p->parent && p->parent->subcommands)
700+
if (p->parent && p->parent->subcommands) {
701701
zhash_delete (p->parent->subcommands, p->program_name);
702+
/*
703+
* zhash_delete() will call optparse_child_destroy(), which
704+
* calls optparse_destroy() again. Return now and allow the
705+
* rest of the optparse object to be freed on the next pass.
706+
* (optparse_child_destroy() set p->parent = NULL)
707+
*
708+
* Note: This code path only occurs if a subcommand optparse
709+
* object is destroyed before its parent.
710+
*/
711+
return;
712+
}
702713

703714
zlist_destroy (&p->option_list);
704715
zhash_destroy (&p->dhash);

0 commit comments

Comments
 (0)