ryantimwilson / rpms / systemd

Forked from rpms/systemd a month ago
Clone
Blob Blame History Raw
From 882c606d2a0d8effbd218059ea7f050c351e4019 Mon Sep 17 00:00:00 2001
From: Harald Hoyer <harald@redhat.com>
Date: Wed, 28 Aug 2013 15:33:35 +0200
Subject: [PATCH] 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.
---
 src/core/cgroup.c | 18 ++++++++++++++----
 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 5a1c3ad..3eeb475 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 0e9329f..ac488cf 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -2337,7 +2337,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;
                 }