Skip to content

Commit

Permalink
libsubcmd: Avoid SEGV/use-after-free when commands aren't excluded
Browse files Browse the repository at this point in the history
The array shortening may perform unnecessary array copies.

Before commit 657a3ef ("lib subcmd: Avoid memory leak in
exclude_cmds") this was benign, but afterwards this could lead to a
SEGV.

Fixes: 657a3ef ("lib subcmd: Avoid memory leak in exclude_cmds")
Signed-off-by: Ian Rogers <irogers@google.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Chenyuan Mi <cymi20@fudan.edu.cn>
Cc: Ian Rogers <irogers@google.com>
Link: https://lore.kernel.org/r/20230707230926.841086-1-irogers@google.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
  • Loading branch information
Ian Rogers authored and Arnaldo Carvalho de Melo committed Jul 11, 2023
1 parent ad07149 commit 4b96679
Showing 1 changed file with 12 additions and 6 deletions.
18 changes: 12 additions & 6 deletions tools/lib/subcmd/help.c
Original file line number Diff line number Diff line change
@@ -68,19 +68,25 @@ void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes)
while (ci < cmds->cnt && ei < excludes->cnt) {
cmp = strcmp(cmds->names[ci]->name, excludes->names[ei]->name);
if (cmp < 0) {
zfree(&cmds->names[cj]);
cmds->names[cj++] = cmds->names[ci++];
if (ci == cj) {
ci++;
cj++;
} else {
zfree(&cmds->names[cj]);
cmds->names[cj++] = cmds->names[ci++];
}
} else if (cmp == 0) {
ci++;
ei++;
} else if (cmp > 0) {
ei++;
}
}

while (ci < cmds->cnt) {
zfree(&cmds->names[cj]);
cmds->names[cj++] = cmds->names[ci++];
if (ci != cj) {
while (ci < cmds->cnt) {
zfree(&cmds->names[cj]);
cmds->names[cj++] = cmds->names[ci++];
}
}
for (ci = cj; ci < cmds->cnt; ci++)
zfree(&cmds->names[ci]);

0 comments on commit 4b96679

Please sign in to comment.