Blob Blame History Raw
From d61ca0aa19cd8c6656428ce7f46b77b4fcccf38d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Date: Thu, 7 Aug 2014 20:42:58 -0400
Subject: [PATCH] core: do not add dependencies to self

Adds a pair of files which cause a segfault (also with
systemd-analyze verify).

https://bugzilla.redhat.com/show_bug.cgi?id=1124843
(cherry picked from commit e66047ff62c971eefa32b42373420d61e3f2a9c1)
---
 src/core/load-dropin.c           |  2 +-
 src/core/unit.c                  | 16 ++++++++++++----
 test/loopy.service               |  2 ++
 test/loopy.service.d/compat.conf |  5 +++++
 test/loopy2.service              |  1 +
 5 files changed, 21 insertions(+), 5 deletions(-)
 create mode 100644 test/loopy.service
 create mode 100644 test/loopy.service.d/compat.conf
 create mode 120000 test/loopy2.service

diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c
index a877e66098..31d0c07f37 100644
--- a/src/core/load-dropin.c
+++ b/src/core/load-dropin.c
@@ -206,7 +206,7 @@ int unit_load_dropin(Unit *u) {
         }
 
         u->dropin_paths = unit_find_dropin_paths(u);
-        if (! u->dropin_paths)
+        if (!u->dropin_paths)
                 return 0;
 
         STRV_FOREACH(f, u->dropin_paths) {
diff --git a/src/core/unit.c b/src/core/unit.c
index c47b2e8265..22d8a7b095 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -551,14 +551,22 @@ static void merge_dependencies(Unit *u, Unit *other, UnitDependency d) {
                 UnitDependency k;
 
                 for (k = 0; k < _UNIT_DEPENDENCY_MAX; k++) {
-                        r = set_remove_and_put(back->dependencies[k], other, u);
-                        if (r == -EEXIST)
+                        /* Do not add dependencies between u and itself */
+                        if (back == u) {
                                 set_remove(back->dependencies[k], other);
-                        else
-                                assert(r >= 0 || r == -ENOENT);
+                        } else {
+                                r = set_remove_and_put(back->dependencies[k], other, u);
+                                if (r == -EEXIST)
+                                        set_remove(back->dependencies[k], other);
+                                else
+                                        assert(r >= 0 || r == -ENOENT);
+                        }
                 }
         }
 
+        /* Also do not move dependencies on u to itself */
+        set_remove(other->dependencies[d], u);
+
         complete_move(&u->dependencies[d], &other->dependencies[d]);
 
         set_free(other->dependencies[d]);
diff --git a/test/loopy.service b/test/loopy.service
new file mode 100644
index 0000000000..9eb645748e
--- /dev/null
+++ b/test/loopy.service
@@ -0,0 +1,2 @@
+[Service]
+ExecStart=/bin/true
diff --git a/test/loopy.service.d/compat.conf b/test/loopy.service.d/compat.conf
new file mode 100644
index 0000000000..51b84b89ed
--- /dev/null
+++ b/test/loopy.service.d/compat.conf
@@ -0,0 +1,5 @@
+[Unit]
+BindsTo=loopy2.service
+
+[Install]
+Also=loopy2.service
diff --git a/test/loopy2.service b/test/loopy2.service
new file mode 120000
index 0000000000..961b1fe9bc
--- /dev/null
+++ b/test/loopy2.service
@@ -0,0 +1 @@
+loopy.service
\ No newline at end of file