summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Synacek <jan.synacek@gmail.com>2017-01-03 21:34:36 +0100
committerMartin Pitt <martin.pitt@ubuntu.com>2017-01-03 21:34:36 +0100
commitdc7dd61de610e9330abe7014860acfa733887d5e (patch)
tree6c25753852f3328ea9e71d46049e7043031ab239
parentfa2a396620adafd861a63e0c151045b56a2151f9 (diff)
downloadsystemd-dc7dd61de610e9330abe7014860acfa733887d5e.tar.gz
shared: fix double free in unmask (#5005)
Easily reproducible: 1) systemctl mask foo 2) systemctl unmask foo foo The problem here is that the *i that is put into todo[] is later freed in strv_uniq(), which is not directly visible from this patch. Somewhere further in the code, the string that *i pointed to is freed again. That happens only when multiple services with the same name/path are specified.
-rw-r--r--src/shared/install.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/src/shared/install.c b/src/shared/install.c
index 4e047157cc..8036b0a404 100644
--- a/src/shared/install.c
+++ b/src/shared/install.c
@@ -1855,7 +1855,7 @@ int unit_file_unmask(
_cleanup_lookup_paths_free_ LookupPaths paths = {};
_cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
- _cleanup_free_ char **todo = NULL;
+ _cleanup_strv_free_ char **todo = NULL;
size_t n_todo = 0, n_allocated = 0;
const char *config_path;
char **i;
@@ -1893,7 +1893,7 @@ int unit_file_unmask(
if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
return -ENOMEM;
- todo[n_todo++] = *i;
+ todo[n_todo++] = strdup(*i);
}
strv_uniq(todo);