Skip to content

Commit 4b96679

Browse files
captain5050acmel
authored andcommitted
libsubcmd: Avoid SEGV/use-after-free when commands aren't excluded
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 <[email protected]> Acked-by: Namhyung Kim <[email protected]> Cc: Chenyuan Mi <[email protected]> Cc: Ian Rogers <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent ad07149 commit 4b96679

File tree

1 file changed

+12
-6
lines changed

1 file changed

+12
-6
lines changed

tools/lib/subcmd/help.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -68,19 +68,25 @@ void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes)
6868
while (ci < cmds->cnt && ei < excludes->cnt) {
6969
cmp = strcmp(cmds->names[ci]->name, excludes->names[ei]->name);
7070
if (cmp < 0) {
71-
zfree(&cmds->names[cj]);
72-
cmds->names[cj++] = cmds->names[ci++];
71+
if (ci == cj) {
72+
ci++;
73+
cj++;
74+
} else {
75+
zfree(&cmds->names[cj]);
76+
cmds->names[cj++] = cmds->names[ci++];
77+
}
7378
} else if (cmp == 0) {
7479
ci++;
7580
ei++;
7681
} else if (cmp > 0) {
7782
ei++;
7883
}
7984
}
80-
81-
while (ci < cmds->cnt) {
82-
zfree(&cmds->names[cj]);
83-
cmds->names[cj++] = cmds->names[ci++];
85+
if (ci != cj) {
86+
while (ci < cmds->cnt) {
87+
zfree(&cmds->names[cj]);
88+
cmds->names[cj++] = cmds->names[ci++];
89+
}
8490
}
8591
for (ci = cj; ci < cmds->cnt; ci++)
8692
zfree(&cmds->names[ci]);

0 commit comments

Comments
 (0)