chiark / gitweb /
service: add minimal access control logic for notifcation socket
[elogind.git] / src / manager.c
index c93b7912eb7df42b3bf6343db611fd1bc59f2c97..c2d5e5f0ef8b84c7f05ae8d1e48a416cae2f1a2a 100644 (file)
@@ -70,7 +70,6 @@ static int manager_setup_notify(Manager *m) {
                 struct sockaddr_un un;
         } sa;
         struct epoll_event ev;
-        char *ne[2], **t;
         int one = 1;
 
         assert(m);
@@ -106,19 +105,9 @@ static int manager_setup_notify(Manager *m) {
         if (epoll_ctl(m->epoll_fd, EPOLL_CTL_ADD, m->notify_watch.fd, &ev) < 0)
                 return -errno;
 
-        if (asprintf(&ne[0], "NOTIFY_SOCKET=@%s", sa.un.sun_path+1) < 0)
+        if (!(m->notify_socket = strdup(sa.un.sun_path+1)))
                 return -ENOMEM;
 
-        ne[1] = NULL;
-        t = strv_env_merge(2, m->environment, ne);
-        free(ne[0]);
-
-        if (!t)
-                return -ENOMEM;
-
-        strv_free(m->environment);
-        m->environment = t;
-
         return 0;
 }
 
@@ -197,6 +186,7 @@ static int manager_setup_signals(Manager *m) {
 int manager_new(ManagerRunningAs running_as, bool confirm_spawn, Manager **_m) {
         Manager *m;
         int r = -ENOMEM;
+        char *p;
 
         assert(_m);
         assert(running_as >= 0);
@@ -211,6 +201,7 @@ int manager_new(ManagerRunningAs running_as, bool confirm_spawn, Manager **_m) {
         m->confirm_spawn = confirm_spawn;
         m->name_data_slot = -1;
         m->exit_code = _MANAGER_EXIT_CODE_INVALID;
+        m->pin_cgroupfs_fd = -1;
 
         m->signal_watch.fd = m->mount_watch.fd = m->udev_watch.fd = m->epoll_fd = m->dev_autofs_fd = -1;
         m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */
@@ -256,6 +247,14 @@ int manager_new(ManagerRunningAs running_as, bool confirm_spawn, Manager **_m) {
             (r = bus_init_api(m)) < 0)
                 goto fail;
 
+        if (asprintf(&p, "%s/%s", m->cgroup_mount_point, m->cgroup_hierarchy) < 0) {
+                r = -ENOMEM;
+                goto fail;
+        }
+
+        m->pin_cgroupfs_fd = open(p, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOCTTY|O_NONBLOCK);
+        free(p);
+
         *_m = m;
         return 0;
 
@@ -441,14 +440,20 @@ void manager_free(Manager *m) {
         if (m->notify_watch.fd >= 0)
                 close_nointr_nofail(m->notify_watch.fd);
 
+        free(m->notify_socket);
+
         lookup_paths_free(&m->lookup_paths);
         strv_free(m->environment);
 
         free(m->cgroup_controller);
         free(m->cgroup_hierarchy);
+        free(m->cgroup_mount_point);
 
         hashmap_free(m->cgroup_bondings);
 
+        if (m->pin_cgroupfs_fd >= 0)
+                close_nointr_nofail(m->pin_cgroupfs_fd);
+
         free(m);
 }
 
@@ -1658,7 +1663,7 @@ static int manager_process_notify_fd(Manager *m) {
                 log_debug("Got notification message for unit %s", u->meta.id);
 
                 if (UNIT_VTABLE(u)->notify_message)
-                        UNIT_VTABLE(u)->notify_message(u, tags);
+                        UNIT_VTABLE(u)->notify_message(u, ucred->pid, tags);
 
                 strv_free(tags);
         }