chiark / gitweb /
core: drop CAP_MKNOD when PrivateDevices= is set
[elogind.git] / src / core / unit.c
index aa723cb8c5929940e283d22f2fa14f913f0146c1..20b139d31be6446aeb2090332a952337d6843988 100644 (file)
@@ -471,6 +471,8 @@ void unit_free(Unit *u) {
                 free(u->cgroup_path);
         }
 
+        set_remove(u->manager->failed_units, u);
+
         free(u->description);
         strv_free(u->documentation);
         free(u->fragment_path);
@@ -1507,6 +1509,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
 
         m = u->manager;
 
+        /* Update timestamps for state changes */
         if (m->n_reloading <= 0) {
                 dual_timestamp ts;
 
@@ -1523,11 +1526,18 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su
                         u->active_exit_timestamp = ts;
         }
 
+        /* Keep track of failed of units */
+        if (ns == UNIT_FAILED && os != UNIT_FAILED)
+                set_put(u->manager->failed_units, u);
+        else if (os == UNIT_FAILED && ns != UNIT_FAILED)
+                set_remove(u->manager->failed_units, u);
+
+        /* Make sure the cgroup is always removed when we become inactive */
         if (UNIT_IS_INACTIVE_OR_FAILED(ns))
                 unit_destroy_cgroup(u);
 
         /* Note that this doesn't apply to RemainAfterExit services exiting
-         * sucessfully, since there's no change of state in that case. Which is
+         * successfully, since there's no change of state in that case. Which is
          * why it is handled in service_set_state() */
         if (UNIT_IS_INACTIVE_OR_FAILED(os) != UNIT_IS_INACTIVE_OR_FAILED(ns)) {
                 ExecContext *ec;
@@ -2820,6 +2830,9 @@ int unit_exec_context_patch_defaults(Unit *u, ExecContext *c) {
              !set_isempty(c->address_families)))
                 c->no_new_privileges = true;
 
+        if (c->private_devices)
+                c->capability_bounding_set_drop |= (uint64_t) 1ULL << (uint64_t) CAP_MKNOD;
+
         return 0;
 }