From: Zbigniew Jędrzejewski-Szmek Date: Tue, 9 Dec 2014 19:41:24 +0000 (-0500) Subject: systemctl: fix invalid free when enabling sysv services fails X-Git-Tag: v218~31 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=commitdiff_plain;h=a644abed54bd4a42ebe2c99af5cc621ffbaf6c55 systemctl: fix invalid free when enabling sysv services fails The error was introduced in v215-343-g60731f32f1 'systemctl: do not bother to mutate state on error', by causing strv_free to attempt to free a static string. Simplify the whole thing by always keeping the array in valid state. --- diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 6e48671ee..17dfff788 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -5143,7 +5143,7 @@ static int enable_sysv_units(const char *verb, char **args) { int r = 0; #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG) - unsigned f = 1, t = 1; + unsigned f = 0; _cleanup_lookup_paths_free_ LookupPaths paths = {}; if (arg_scope != UNIT_FILE_SYSTEM) @@ -5162,7 +5162,7 @@ static int enable_sysv_units(const char *verb, char **args) { return r; r = 0; - for (f = 0; args[f]; f++) { + while (args[f]) { const char *name; _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL; bool found_native = false, found_sysv; @@ -5173,7 +5173,7 @@ static int enable_sysv_units(const char *verb, char **args) { pid_t pid; siginfo_t status; - name = args[f]; + name = args[f++]; if (!endswith(name, ".service")) continue; @@ -5205,9 +5205,6 @@ static int enable_sysv_units(const char *verb, char **args) { if (!found_sysv) continue; - /* Mark this entry, so that we don't try enabling it as native unit */ - args[f] = (char*) ""; - log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name); if (!isempty(arg_root)) @@ -5256,19 +5253,12 @@ static int enable_sysv_units(const char *verb, char **args) { return -EINVAL; } else return -EPROTO; - } - - /* Drop all SysV units */ - for (f = 0, t = 0; args[f]; f++) { - if (isempty(args[f])) - continue; - - args[t++] = args[f]; + /* Remove this entry, so that we don't try enabling it as native unit */ + assert(f > 0 && streq(args[f-1], name)); + assert_se(strv_remove(args + f - 1, name)); } - args[t] = NULL; - #endif return r; }