[systemd-commits] 3 commits - src/libsystemd-bus

Lennart Poettering lennart at kemper.freedesktop.org
Thu Mar 21 16:12:48 PDT 2013


 src/libsystemd-bus/bus-internal.h  |    7 ++
 src/libsystemd-bus/sd-bus.c        |   89 +++++++++++++++++++++++++++++++++----
 src/libsystemd-bus/sd-bus.h        |    5 --
 src/libsystemd-bus/test-bus-chat.c |   35 ++++++++++++++
 4 files changed, 122 insertions(+), 14 deletions(-)

New commits:
commit b9bf7e2be93fe25e0e96e06ad436d43a1e589ed5
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Mar 22 00:08:58 2013 +0100

    bus: implicitly handle peer commands Ping() and GetMachineId()

diff --git a/src/libsystemd-bus/bus-internal.h b/src/libsystemd-bus/bus-internal.h
index b0e9791..636e998 100644
--- a/src/libsystemd-bus/bus-internal.h
+++ b/src/libsystemd-bus/bus-internal.h
@@ -108,6 +108,7 @@ static inline void bus_unrefp(sd_bus **b) {
 }
 
 #define _cleanup_bus_unref_ __attribute__((cleanup(bus_unrefp)))
+#define _cleanup_bus_error_free_ __attribute__((cleanup(sd_bus_error_free)))
 
 #define BUS_DEFAULT_TIMEOUT ((usec_t) (25 * USEC_PER_SEC))
 
diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c
index 1dd234d..049bd35 100644
--- a/src/libsystemd-bus/sd-bus.c
+++ b/src/libsystemd-bus/sd-bus.c
@@ -1475,6 +1475,57 @@ static int process_timeout(sd_bus *bus) {
         return r < 0 ? r : 1;
 }
 
+static int process_builtin(sd_bus *bus, sd_bus_message *m) {
+        _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+        int r;
+
+        assert(bus);
+        assert(m);
+
+        if (m->header->type != SD_BUS_MESSAGE_TYPE_METHOD_CALL)
+                return 0;
+
+        if (!streq_ptr(m->interface, "org.freedesktop.DBus.Peer"))
+                return 0;
+
+        if (m->header->flags & SD_BUS_MESSAGE_NO_REPLY_EXPECTED)
+                return 1;
+
+        if (streq_ptr(m->member, "Ping"))
+                r = sd_bus_message_new_method_return(bus, m, &reply);
+        else if (streq_ptr(m->member, "GetMachineId")) {
+                sd_id128_t id;
+                char sid[33];
+
+                r = sd_id128_get_machine(&id);
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_message_new_method_return(bus, m, &reply);
+                if (r < 0)
+                        return r;
+
+                r = sd_bus_message_append(reply, "s", sd_id128_to_string(id, sid));
+        } else {
+                _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_INIT;
+
+                sd_bus_error_set(&error,
+                                 "org.freedesktop.DBus.Error.UnknownMethod",
+                                 "Unknown method '%s' on interface '%s'.", m->member, m->interface);
+
+                r = sd_bus_message_new_method_error(bus, m, &error, &reply);
+        }
+
+        if (r < 0)
+                return r;
+
+        r = sd_bus_send(bus, reply, NULL);
+        if (r < 0)
+                return r;
+
+        return 1;
+}
+
 static int process_message(sd_bus *bus, sd_bus_message *m) {
         struct filter_callback *l;
         int r;
@@ -1482,7 +1533,7 @@ static int process_message(sd_bus *bus, sd_bus_message *m) {
         assert(bus);
         assert(m);
 
-        if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL || m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_RETURN) {
+        if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_RETURN || m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_ERROR) {
                 struct reply_callback *c;
 
                 c = hashmap_remove(bus->reply_callbacks, &m->reply_serial);
@@ -1504,7 +1555,7 @@ static int process_message(sd_bus *bus, sd_bus_message *m) {
                         return r;
         }
 
-        return 0;
+        return process_builtin(bus, m);
 }
 
 int sd_bus_process(sd_bus *bus, sd_bus_message **ret) {
@@ -1599,11 +1650,13 @@ int sd_bus_process(sd_bus *bus, sd_bus_message **ret) {
                         return 1;
                 }
 
-                if (sd_bus_message_is_method_call(m, NULL, NULL)) {
-                        const sd_bus_error e = SD_BUS_ERROR_INIT_CONST("org.freedesktop.DBus.Error.UnknownObject", "Unknown object.");
+                if (m->header->type == SD_BUS_MESSAGE_TYPE_METHOD_CALL) {
                         _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
+                        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_INIT;
+
+                        sd_bus_error_set(&error, "org.freedesktop.DBus.Error.UnknownObject", "Unknown object '%s'.", m->path);
 
-                        r = sd_bus_message_new_method_error(bus, m, &e, &reply);
+                        r = sd_bus_message_new_method_error(bus, m, &error, &reply);
                         if (r < 0)
                                 return r;
 
diff --git a/src/libsystemd-bus/sd-bus.h b/src/libsystemd-bus/sd-bus.h
index 1d7bfa8..d5101c2 100644
--- a/src/libsystemd-bus/sd-bus.h
+++ b/src/libsystemd-bus/sd-bus.h
@@ -36,8 +36,8 @@
  * - handle NULL strings nicer when appending
  * - merge busctl into systemctl or so?
  * - add object handlers
- * - add peer message handlers
  * - verify object paths
+ * - implicitly add stub introspection calls
  */
 
 typedef struct sd_bus sd_bus;
diff --git a/src/libsystemd-bus/test-bus-chat.c b/src/libsystemd-bus/test-bus-chat.c
index 9e14824..d8677cc 100644
--- a/src/libsystemd-bus/test-bus-chat.c
+++ b/src/libsystemd-bus/test-bus-chat.c
@@ -264,8 +264,9 @@ static void* client2(void*p) {
         _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
         sd_bus *bus = NULL;
         sd_bus_error error = SD_BUS_ERROR_INIT;
-        int r;
         bool quit = false;
+        const char *mid;
+        int r;
 
         r = sd_bus_open_user(&bus);
         if (r < 0) {
@@ -277,6 +278,35 @@ static void* client2(void*p) {
                         bus,
                         "org.freedesktop.systemd.test",
                         "/",
+                        "org.freedesktop.DBus.Peer",
+                        "GetMachineId",
+                        &m);
+        if (r < 0) {
+                log_error("Failed to allocate method call: %s", strerror(-r));
+                goto finish;
+        }
+
+        r = sd_bus_send_with_reply_and_block(bus, m, 0, &error, &reply);
+        if (r < 0) {
+                log_error("Failed to issue method call: %s", bus_error_message(&error, -r));
+                goto finish;
+        }
+
+        r = sd_bus_message_read(reply, "s", &mid);
+        if (r < 0) {
+                log_error("Failed to parse machine ID: %s", strerror(-r));
+                goto finish;
+        }
+
+        log_info("Machine ID is %s.", mid);
+
+        sd_bus_message_unref(m);
+        m = NULL;
+
+        r = sd_bus_message_new_method_call(
+                        bus,
+                        "org.freedesktop.systemd.test",
+                        "/",
                         "org.freedesktop.systemd.test",
                         "Slow",
                         &m);
@@ -285,6 +315,9 @@ static void* client2(void*p) {
                 goto finish;
         }
 
+        sd_bus_message_unref(reply);
+        reply = NULL;
+
         r = sd_bus_send_with_reply_and_block(bus, m, 200 * USEC_PER_MSEC, &error, &reply);
         if (r < 0)
                 log_info("Failed to issue method call: %s", bus_error_message(&error, -r));

commit 25220239990c7859a65160d63277105d0c1de8a8
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Mar 21 23:20:25 2013 +0100

    bus: enforce limits on all client influenced data objects

diff --git a/src/libsystemd-bus/bus-internal.h b/src/libsystemd-bus/bus-internal.h
index 9e4cf16..b0e9791 100644
--- a/src/libsystemd-bus/bus-internal.h
+++ b/src/libsystemd-bus/bus-internal.h
@@ -110,3 +110,9 @@ static inline void bus_unrefp(sd_bus **b) {
 #define _cleanup_bus_unref_ __attribute__((cleanup(bus_unrefp)))
 
 #define BUS_DEFAULT_TIMEOUT ((usec_t) (25 * USEC_PER_SEC))
+
+#define BUS_WQUEUE_MAX 128
+#define BUS_RQUEUE_MAX 128
+
+#define BUS_MESSAGE_SIZE_MAX (64*1024*1024)
+#define BUS_AUTH_SIZE_MAX (64*1024)
diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c
index ad840cc..1dd234d 100644
--- a/src/libsystemd-bus/sd-bus.c
+++ b/src/libsystemd-bus/sd-bus.c
@@ -35,8 +35,6 @@
 #include "bus-message.h"
 #include "bus-type.h"
 
-#define WQUEUE_MAX 128
-
 static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec);
 
 static void bus_free(sd_bus *b) {
@@ -495,6 +493,13 @@ static int bus_read_auth(sd_bus *b) {
                 return r;
 
         n = MAX(3 + 32 + 2 + sizeof("AGREE_UNIX_FD") - 1 + 2, b->rbuffer_size * 2);
+
+        if (n > BUS_AUTH_SIZE_MAX)
+                n = BUS_AUTH_SIZE_MAX;
+
+        if (b->rbuffer_size >= n)
+                return -ENOBUFS;
+
         p = realloc(b->rbuffer, n);
         if (!p)
                 return -ENOMEM;
@@ -845,6 +850,7 @@ static int message_write(sd_bus *bus, sd_bus_message *m, size_t *idx) {
 static int message_read_need(sd_bus *bus, size_t *need) {
         uint32_t a, b;
         uint8_t e;
+        uint64_t sum;
 
         assert(bus);
         assert(need);
@@ -885,7 +891,11 @@ static int message_read_need(sd_bus *bus, size_t *need) {
         } else
                 return -EBADMSG;
 
-        *need = sizeof(struct bus_header) + ALIGN_TO(b, 8) + a;
+        sum = (uint64_t) sizeof(struct bus_header) + (uint64_t) ALIGN_TO(b, 8) + (uint64_t) a;
+        if (sum >= BUS_MESSAGE_SIZE_MAX)
+                return -ENOBUFS;
+
+        *need = (size_t) sum;
         return 0;
 }
 
@@ -1093,7 +1103,7 @@ int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *serial) {
 
                 /* Just append it to the queue. */
 
-                if (bus->wqueue_size >= WQUEUE_MAX)
+                if (bus->wqueue_size >= BUS_WQUEUE_MAX)
                         return -ENOBUFS;
 
                 q = realloc(bus->wqueue, sizeof(sd_bus_message*) * (bus->wqueue_size + 1));
@@ -1300,6 +1310,9 @@ int sd_bus_send_with_reply_and_block(
                 if (!room) {
                         sd_bus_message **q;
 
+                        if (bus->rqueue_size >= BUS_RQUEUE_MAX)
+                                return -ENOBUFS;
+
                         /* Make sure there's room for queuing this
                          * locally, before we read the message */
 
diff --git a/src/libsystemd-bus/sd-bus.h b/src/libsystemd-bus/sd-bus.h
index a759f54..1d7bfa8 100644
--- a/src/libsystemd-bus/sd-bus.h
+++ b/src/libsystemd-bus/sd-bus.h
@@ -38,8 +38,6 @@
  * - add object handlers
  * - add peer message handlers
  * - verify object paths
- * - when reading a message, verify its size
- * - add limits to wqueue and rqueue alike
  */
 
 typedef struct sd_bus sd_bus;

commit 29f6aadd5302320d5a7a3868b607eb83687bdfd0
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Mar 21 23:01:59 2013 +0100

    bus: implicitly set no_reply flag on outgoing messages if the serial number is not kept
    
    If nobody keeps the serial number of an outgoing message we know that
    nobody expects an answer to it, so set the no_reply flag accordingly.

diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c
index d0a3608..ad840cc 100644
--- a/src/libsystemd-bus/sd-bus.c
+++ b/src/libsystemd-bus/sd-bus.c
@@ -1057,6 +1057,11 @@ int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *serial) {
         if (!m)
                 return -EINVAL;
 
+        /* If the serial number isn't kept, then we know that no reply
+         * is expected */
+        if (!serial && !m->sealed)
+                m->header->flags |= SD_BUS_MESSAGE_NO_REPLY_EXPECTED;
+
         r = bus_seal_message(bus, m);
         if (r < 0)
                 return r;
diff --git a/src/libsystemd-bus/sd-bus.h b/src/libsystemd-bus/sd-bus.h
index ce92ee7..a759f54 100644
--- a/src/libsystemd-bus/sd-bus.h
+++ b/src/libsystemd-bus/sd-bus.h
@@ -33,7 +33,6 @@
  * - add page donation logic
  * - api for appending/reading fixed arrays
  * - always verify container depth
- * - implicitly set no_reply when a message-call is sent an the serial number ignored
  * - handle NULL strings nicer when appending
  * - merge busctl into systemctl or so?
  * - add object handlers



More information about the systemd-commits mailing list