[systemd-commits] 3 commits - src/fsckd units/systemd-fsckd.socket

Lennart Poettering lennart at kemper.freedesktop.org
Mon Mar 9 11:38:30 PDT 2015


 src/fsckd/fsckd.c          |   52 +++++++++++++++++++++++++++++++++------------
 units/systemd-fsckd.socket |    1 
 2 files changed, 40 insertions(+), 13 deletions(-)

New commits:
commit e78e0674f3ec8512370110383889848dc662639b
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Mar 9 19:36:46 2015 +0100

    fsckd: don't allow unbounded numbers of clients

diff --git a/src/fsckd/fsckd.c b/src/fsckd/fsckd.c
index c4135a5..4851b92 100644
--- a/src/fsckd/fsckd.c
+++ b/src/fsckd/fsckd.c
@@ -47,6 +47,7 @@
 
 #define IDLE_TIME_SECONDS 30
 #define PLYMOUTH_REQUEST_KEY "K\2\2\3"
+#define CLIENTS_MAX 128
 
 struct Manager;
 
@@ -73,6 +74,7 @@ typedef struct Manager {
         sd_event *event;
 
         LIST_HEAD(Client, clients);
+        unsigned n_clients;
 
         int clear;
         int connection_fd;
@@ -139,8 +141,10 @@ static int client_request_cancel(Client *c) {
 static void client_free(Client *c) {
         assert(c);
 
-        if (c->manager)
+        if (c->manager) {
                 LIST_REMOVE(clients, c->manager->clients, c);
+                c->manager->n_clients--;
+        }
 
         sd_event_source_unref(c->event_source);
 
@@ -380,8 +384,9 @@ static int client_progress_handler(sd_event_source *s, int fd, uint32_t revents,
 
 static int manager_new_connection_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
         _cleanup_(client_freep) Client *c = NULL;
+        _cleanup_close_ int new_client_fd = -1;
         Manager *m = userdata;
-        int new_client_fd, r;
+        int r;
 
         assert(m);
 
@@ -390,16 +395,22 @@ static int manager_new_connection_handler(sd_event_source *s, int fd, uint32_t r
         if (new_client_fd < 0)
                 return log_error_errno(errno, "Couldn't accept a new connection: %m");
 
+        if (m->n_clients >= CLIENTS_MAX) {
+                log_error("Too many clients, refusing connection.");
+                return 0;
+        }
+
         log_debug("New fsck client connected to fd: %d", new_client_fd);
 
         c = new0(Client, 1);
         if (!c) {
-                safe_close(new_client_fd);
                 log_oom();
                 return 0;
         }
 
         c->fd = new_client_fd;
+        new_client_fd = -1;
+
         r = sd_event_add_io(m->event, &c->event_source, c->fd, EPOLLIN, client_progress_handler, c);
         if (r < 0) {
                 log_oom();
@@ -407,6 +418,7 @@ static int manager_new_connection_handler(sd_event_source *s, int fd, uint32_t r
         }
 
         LIST_PREPEND(clients, m->clients, c);
+        m->n_clients++;
         c->manager = m;
 
         /* only request the client to cancel now in case the request is dropped by the client (chance to recancel) */

commit 35682f425f2dee9d38a0ff4931b1eb25bb206dee
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Mar 9 19:34:10 2015 +0100

    fsckd: make sure unprivileged clients cannot play games with fsckd

diff --git a/units/systemd-fsckd.socket b/units/systemd-fsckd.socket
index 93c4ea9..92e8eef 100644
--- a/units/systemd-fsckd.socket
+++ b/units/systemd-fsckd.socket
@@ -12,3 +12,4 @@ DefaultDependencies=no
 
 [Socket]
 ListenStream=/run/systemd/fsckd
+SocketMode=0600

commit d42688ef21a695f8a30b0d899dafdc6ff1ee0973
Author: Lennart Poettering <lennart at poettering.net>
Date:   Mon Mar 9 19:33:49 2015 +0100

    fsckd: free client event source before we close its fd

diff --git a/src/fsckd/fsckd.c b/src/fsckd/fsckd.c
index 36b890a..c4135a5 100644
--- a/src/fsckd/fsckd.c
+++ b/src/fsckd/fsckd.c
@@ -64,6 +64,8 @@ typedef struct Client {
         size_t buflen;
         bool cancelled;
 
+        sd_event_source *event_source;
+
         LIST_FIELDS(struct Client, clients);
 } Client;
 
@@ -86,7 +88,10 @@ typedef struct Manager {
         bool cancel_requested;
 } Manager;
 
+static void client_free(Client *c);
 static void manager_free(Manager *m);
+
+DEFINE_TRIVIAL_CLEANUP_FUNC(Client*, client_free);
 DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
 
 static double compute_percent(int pass, size_t cur, size_t max) {
@@ -137,6 +142,8 @@ static void client_free(Client *c) {
         if (c->manager)
                 LIST_REMOVE(clients, c->manager->clients, c);
 
+        sd_event_source_unref(c->event_source);
+
         safe_close(c->fd);
         free(c);
 }
@@ -372,8 +379,8 @@ static int client_progress_handler(sd_event_source *s, int fd, uint32_t revents,
 }
 
 static int manager_new_connection_handler(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
+        _cleanup_(client_freep) Client *c = NULL;
         Manager *m = userdata;
-        Client *client = NULL;
         int new_client_fd, r;
 
         assert(m);
@@ -385,21 +392,28 @@ static int manager_new_connection_handler(sd_event_source *s, int fd, uint32_t r
 
         log_debug("New fsck client connected to fd: %d", new_client_fd);
 
-        client = new0(Client, 1);
-        if (!client)
-                return log_oom();
-        client->fd = new_client_fd;
-        client->manager = m;
-        LIST_PREPEND(clients, m->clients, client);
-        r = sd_event_add_io(m->event, NULL, client->fd, EPOLLIN, client_progress_handler, client);
+        c = new0(Client, 1);
+        if (!c) {
+                safe_close(new_client_fd);
+                log_oom();
+                return 0;
+        }
+
+        c->fd = new_client_fd;
+        r = sd_event_add_io(m->event, &c->event_source, c->fd, EPOLLIN, client_progress_handler, c);
         if (r < 0) {
-                client_free(client);
-                return r;
+                log_oom();
+                return 0;
         }
+
+        LIST_PREPEND(clients, m->clients, c);
+        c->manager = m;
+
         /* only request the client to cancel now in case the request is dropped by the client (chance to recancel) */
         if (m->cancel_requested)
-                client_request_cancel(client);
+                client_request_cancel(c);
 
+        c = NULL;
         return 0;
 }
 



More information about the systemd-commits mailing list