diff options
author | Harald Hoyer <harald@redhat.com> | 2013-08-28 15:33:35 +0200 |
---|---|---|
committer | Harald Hoyer <harald@redhat.com> | 2013-08-28 16:02:57 +0200 |
commit | b58b8e11c5f769e3c80d5169fdcc4bd04b882b7d (patch) | |
tree | f0ab4e44f8910ae63c9b017736d36bca3ebfe9c1 | |
parent | 3d040cf24473f2ed13121d57ed753bad5f8ad09d (diff) |
Do not realloc strings, which are already in the hashmap as keys
This prevents corruption of the hashmap, because we would free() the
keys in the hashmap, if the unit is already in there, with the same
cgroup path.
-rw-r--r-- | src/core/cgroup.c | 18 | ||||
-rw-r--r-- | src/core/unit.c | 2 |
2 files changed, 15 insertions, 5 deletions
diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 5a1c3adacd..3eeb475754 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -382,6 +382,7 @@ static CGroupControllerMask unit_get_siblings_mask(Unit *u) { static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) { char *path = NULL; int r; + bool is_in_hash = false; assert(u); @@ -390,8 +391,14 @@ static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) { return -ENOMEM; r = hashmap_put(u->manager->cgroup_unit, path, u); - if (r < 0) + if (r == 0) + is_in_hash = true; + + if (r < 0) { + free(path); + log_error("cgroup %s exists already: %s", path, strerror(-r)); return r; + } /* First, create our own group */ r = cg_create_with_mask(mask, path); @@ -405,9 +412,12 @@ static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) { log_error("Failed to migrate cgroup %s: %s", path, strerror(-r)); } - /* And remember the new data */ - free(u->cgroup_path); - u->cgroup_path = path; + if (!is_in_hash) { + /* And remember the new data */ + free(u->cgroup_path); + u->cgroup_path = path; + } + u->cgroup_realized = true; u->cgroup_mask = mask; diff --git a/src/core/unit.c b/src/core/unit.c index 27119b0cd7..ab313b9b91 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -2329,7 +2329,7 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { free(u->cgroup_path); u->cgroup_path = s; - hashmap_put(u->manager->cgroup_unit, s, u); + assert(hashmap_put(u->manager->cgroup_unit, s, u) == 1); continue; } |