summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/basic/alloc-util.h7
-rw-r--r--src/systemctl/systemctl-kill.c2
-rw-r--r--src/systemctl/systemctl-start-unit.c2
-rw-r--r--src/systemctl/systemctl.c15
-rw-r--r--src/systemctl/systemctl.h6
-rw-r--r--test/fuzz/fuzz-systemctl-parse-argv/oss-fuzz-31714bin0 -> 132 bytes
6 files changed, 24 insertions, 8 deletions
diff --git a/src/basic/alloc-util.h b/src/basic/alloc-util.h
index 99fbd3a889..3c33308f48 100644
--- a/src/basic/alloc-util.h
+++ b/src/basic/alloc-util.h
@@ -79,6 +79,13 @@ void* memdup_suffix0(const void *p, size_t l); /* We can't use _alloc_() here, s
memcpy_safe(_q_, p, _l_); \
})
+static inline void unsetp(void *p) {
+ /* A trivial "destructor" that can be used in cases where we want to
+ * unset a pointer from a _cleanup_ function. */
+
+ *(void**)p = NULL;
+}
+
static inline void freep(void *p) {
*(void**)p = mfree(*(void**) p);
}
diff --git a/src/systemctl/systemctl-kill.c b/src/systemctl/systemctl-kill.c
index 810aad108a..489e754752 100644
--- a/src/systemctl/systemctl-kill.c
+++ b/src/systemctl/systemctl-kill.c
@@ -22,7 +22,7 @@ int kill_unit(int argc, char *argv[], void *userdata) {
arg_kill_who = "all";
/* --fail was specified */
- if (streq(arg_job_mode, "fail"))
+ if (streq(arg_job_mode(), "fail"))
kill_who = strjoina(arg_kill_who, "-fail");
r = expand_unit_names(bus, strv_skip(argv, 1), NULL, &names, NULL);
diff --git a/src/systemctl/systemctl-start-unit.c b/src/systemctl/systemctl-start-unit.c
index 096b8ada20..274b278d2d 100644
--- a/src/systemctl/systemctl-start-unit.c
+++ b/src/systemctl/systemctl-start-unit.c
@@ -306,7 +306,7 @@ int start_unit(int argc, char *argv[], void *userdata) {
/* A command in style of "systemctl start <unit1> <unit2> …", "sysemctl stop <unit1> <unit2> …" and so on */
method = verb_to_method(argv[0]);
job_type = verb_to_job_type(argv[0]);
- mode = arg_job_mode;
+ mode = arg_job_mode();
} else
method = job_type = mode = NULL;
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index a4100bd554..e37569ab7f 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -65,7 +65,7 @@ char **arg_states = NULL;
char **arg_properties = NULL;
bool arg_all = false;
enum dependency arg_dependency = DEPENDENCY_FORWARD;
-const char *arg_job_mode = "replace";
+const char *_arg_job_mode = NULL;
UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
bool arg_wait = false;
bool arg_no_block = false;
@@ -115,8 +115,13 @@ bool arg_marked = false;
STATIC_DESTRUCTOR_REGISTER(arg_types, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_states, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_properties, strv_freep);
+STATIC_DESTRUCTOR_REGISTER(_arg_job_mode, unsetp);
STATIC_DESTRUCTOR_REGISTER(arg_wall, strv_freep);
+STATIC_DESTRUCTOR_REGISTER(arg_kill_who, unsetp);
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
+STATIC_DESTRUCTOR_REGISTER(arg_reboot_argument, unsetp);
+STATIC_DESTRUCTOR_REGISTER(arg_host, unsetp);
+STATIC_DESTRUCTOR_REGISTER(arg_boot_loader_entry, unsetp);
STATIC_DESTRUCTOR_REGISTER(arg_clean_what, strv_freep);
static int systemctl_help(void) {
@@ -598,19 +603,19 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
break;
case ARG_JOB_MODE:
- arg_job_mode = optarg;
+ _arg_job_mode = optarg;
break;
case ARG_FAIL:
- arg_job_mode = "fail";
+ _arg_job_mode = "fail";
break;
case ARG_IRREVERSIBLE:
- arg_job_mode = "replace-irreversibly";
+ _arg_job_mode = "replace-irreversibly";
break;
case ARG_IGNORE_DEPENDENCIES:
- arg_job_mode = "ignore-dependencies";
+ _arg_job_mode = "ignore-dependencies";
break;
case ARG_USER:
diff --git a/src/systemctl/systemctl.h b/src/systemctl/systemctl.h
index ed8152e3dd..8199ae9e0d 100644
--- a/src/systemctl/systemctl.h
+++ b/src/systemctl/systemctl.h
@@ -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[]);
diff --git a/test/fuzz/fuzz-systemctl-parse-argv/oss-fuzz-31714 b/test/fuzz/fuzz-systemctl-parse-argv/oss-fuzz-31714
new file mode 100644
index 0000000000..dfb14cd762
--- /dev/null
+++ b/test/fuzz/fuzz-systemctl-parse-argv/oss-fuzz-31714
Binary files differ