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.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2021-05-31 19:29:07 +02:00
parent 6b42227edb
commit a88f9dbae2
6 changed files with 24 additions and 8 deletions
+5 -1
View File
@@ -49,7 +49,7 @@ extern char **arg_states;
extern char **arg_properties;
extern bool arg_all;
extern enum dependency arg_dependency;
extern const char *arg_job_mode;
extern const char *_arg_job_mode;
extern UnitFileScope arg_scope;
extern bool arg_wait;
extern bool arg_no_block;
@@ -96,4 +96,8 @@ extern bool arg_read_only;
extern bool arg_mkdir;
extern bool arg_marked;
static inline const char* arg_job_mode(void) {
return _arg_job_mode ?: "replace";
}
int systemctl_dispatch_parse_argv(int argc, char *argv[]);