summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHarald Hoyer <harald@redhat.com>2013-08-28 15:33:35 +0200
committerHarald Hoyer <harald@redhat.com>2013-08-28 16:02:57 +0200
commitb58b8e11c5f769e3c80d5169fdcc4bd04b882b7d (patch)
treef0ab4e44f8910ae63c9b017736d36bca3ebfe9c1
parent3d040cf24473f2ed13121d57ed753bad5f8ad09d (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.
Notes
Backport: bugfix
-rw-r--r--src/core/cgroup.c18
-rw-r--r--src/core/unit.c2
2 files changed, 15 insertions, 5 deletions
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index 5a1c3adac..3eeb47575 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 27119b0cd..ab313b9b9 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;
}