Harald Hoyer fe20ad
From 882c606d2a0d8effbd218059ea7f050c351e4019 Mon Sep 17 00:00:00 2001
Harald Hoyer fe20ad
From: Harald Hoyer <harald@redhat.com>
Harald Hoyer fe20ad
Date: Wed, 28 Aug 2013 15:33:35 +0200
Harald Hoyer fe20ad
Subject: [PATCH] Do not realloc strings, which are already in the hashmap as
Harald Hoyer fe20ad
 keys
Harald Hoyer fe20ad
Harald Hoyer fe20ad
This prevents corruption of the hashmap, because we would free() the
Harald Hoyer fe20ad
keys in the hashmap, if the unit is already in there, with the same
Harald Hoyer fe20ad
cgroup path.
Harald Hoyer fe20ad
---
Harald Hoyer fe20ad
 src/core/cgroup.c | 18 ++++++++++++++----
Harald Hoyer fe20ad
 src/core/unit.c   |  2 +-
Harald Hoyer fe20ad
 2 files changed, 15 insertions(+), 5 deletions(-)
Harald Hoyer fe20ad
Harald Hoyer fe20ad
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
Harald Hoyer fe20ad
index 5a1c3ad..3eeb475 100644
Harald Hoyer fe20ad
--- a/src/core/cgroup.c
Harald Hoyer fe20ad
+++ b/src/core/cgroup.c
Harald Hoyer fe20ad
@@ -382,6 +382,7 @@ static CGroupControllerMask unit_get_siblings_mask(Unit *u) {
Harald Hoyer fe20ad
 static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) {
Harald Hoyer fe20ad
         char *path = NULL;
Harald Hoyer fe20ad
         int r;
Harald Hoyer fe20ad
+        bool is_in_hash = false;
Harald Hoyer fe20ad
 
Harald Hoyer fe20ad
         assert(u);
Harald Hoyer fe20ad
 
Harald Hoyer fe20ad
@@ -390,8 +391,14 @@ static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) {
Harald Hoyer fe20ad
                 return -ENOMEM;
Harald Hoyer fe20ad
 
Harald Hoyer fe20ad
         r = hashmap_put(u->manager->cgroup_unit, path, u);
Harald Hoyer fe20ad
-        if (r < 0)
Harald Hoyer fe20ad
+        if (r == 0)
Harald Hoyer fe20ad
+                is_in_hash = true;
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
+        if (r < 0) {
Harald Hoyer fe20ad
+                free(path);
Harald Hoyer fe20ad
+                log_error("cgroup %s exists already: %s", path, strerror(-r));
Harald Hoyer fe20ad
                 return r;
Harald Hoyer fe20ad
+        }
Harald Hoyer fe20ad
 
Harald Hoyer fe20ad
         /* First, create our own group */
Harald Hoyer fe20ad
         r = cg_create_with_mask(mask, path);
Harald Hoyer fe20ad
@@ -405,9 +412,12 @@ static int unit_create_cgroups(Unit *u, CGroupControllerMask mask) {
Harald Hoyer fe20ad
                         log_error("Failed to migrate cgroup %s: %s", path, strerror(-r));
Harald Hoyer fe20ad
         }
Harald Hoyer fe20ad
 
Harald Hoyer fe20ad
-        /* And remember the new data */
Harald Hoyer fe20ad
-        free(u->cgroup_path);
Harald Hoyer fe20ad
-        u->cgroup_path = path;
Harald Hoyer fe20ad
+        if (!is_in_hash) {
Harald Hoyer fe20ad
+                /* And remember the new data */
Harald Hoyer fe20ad
+                free(u->cgroup_path);
Harald Hoyer fe20ad
+                u->cgroup_path = path;
Harald Hoyer fe20ad
+        }
Harald Hoyer fe20ad
+
Harald Hoyer fe20ad
         u->cgroup_realized = true;
Harald Hoyer fe20ad
         u->cgroup_mask = mask;
Harald Hoyer fe20ad
 
Harald Hoyer fe20ad
diff --git a/src/core/unit.c b/src/core/unit.c
Harald Hoyer fe20ad
index 0e9329f..ac488cf 100644
Harald Hoyer fe20ad
--- a/src/core/unit.c
Harald Hoyer fe20ad
+++ b/src/core/unit.c
Harald Hoyer fe20ad
@@ -2337,7 +2337,7 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) {
Harald Hoyer fe20ad
                         free(u->cgroup_path);
Harald Hoyer fe20ad
                         u->cgroup_path = s;
Harald Hoyer fe20ad
 
Harald Hoyer fe20ad
-                        hashmap_put(u->manager->cgroup_unit, s, u);
Harald Hoyer fe20ad
+                        assert(hashmap_put(u->manager->cgroup_unit, s, u) == 1);
Harald Hoyer fe20ad
                         continue;
Harald Hoyer fe20ad
                 }
Harald Hoyer fe20ad