systemctl: unset const char* arguments in static destructors
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 31 May 2021 09:23:20 +0000 (11:23 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Mon, 31 May 2021 17:29:07 +0000 (19:29 +0200)
commita88f9dbae2cbd2af6016e7f4dab5b7a0771491c6
tree346d30a31c2b1ebdce8e1d10f8c4b811fbdc221e
parent6b42227edb78193294d8096d39751b5fa45985e7
systemctl: unset const char* arguments in static destructors

When fuzzing, the following happens:
- we parse 'data' and produce an argv array,
- one of the items in argv is assigned to arg_host,
- the argv array is subsequently freed by strv_freep(), and arg_host has a dangling symlink.

In normal use, argv is static, so arg_host can never become a dangling pointer.
In fuzz-systemctl-parse-argv, if we repeatedly parse the same array, we
have some dangling pointers while we're in the middle of parsing. If we parse
the same array a second time, at the end all the dangling pointers will have been
replaced again. But for a short time, if parsing one of the arguments uses another
argument, we would use a dangling pointer.

Such a case occurs when we have --host=… --boot-loader-entry=help. The latter calls
acquire_bus() which uses arg_host.

I'm not particularly happy with making the code more complicated just for
fuzzing, but I think it's better to resolve this, even if the issue cannot
occur in normal invocations, than to deal with fuzzer reports.

Should fix https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=31714.
src/basic/alloc-util.h
src/systemctl/systemctl-kill.c
src/systemctl/systemctl-start-unit.c
src/systemctl/systemctl.c
src/systemctl/systemctl.h
test/fuzz/fuzz-systemctl-parse-argv/oss-fuzz-31714 [new file with mode: 0644]