Commit 4b966791 authored by Ian Rogers's avatar Ian Rogers Committed by Arnaldo Carvalho de Melo
Browse files

libsubcmd: Avoid SEGV/use-after-free when commands aren't excluded



The array shortening may perform unnecessary array copies.

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

Fixes: 657a3efe ("lib subcmd: Avoid memory leak in exclude_cmds")
Signed-off-by: default avatarIan Rogers <irogers@google.com>
Acked-by: default avatarNamhyung 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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent ad07149f
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -68,8 +68,13 @@ 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) {
			if (ci == cj) {
				ci++;
				cj++;
			} else {
				zfree(&cmds->names[cj]);
				cmds->names[cj++] = cmds->names[ci++];
			}
		} else if (cmp == 0) {
			ci++;
			ei++;
@@ -77,11 +82,12 @@ void exclude_cmds(struct cmdnames *cmds, struct cmdnames *excludes)
			ei++;
		}
	}

	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]);
	cmds->cnt = cj;