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

Lennart Poettering lennart at kemper.freedesktop.org
Thu Mar 21 18:20:50 PDT 2013


 src/libsystemd-bus/bus-message.c        |   56 ++++++++++++++------------------
 src/libsystemd-bus/bus-signature.c      |   28 +++++++++++-----
 src/libsystemd-bus/sd-bus.c             |   55 +++++++++++++++++--------------
 src/libsystemd-bus/sd-bus.h             |    5 +-
 src/libsystemd-bus/test-bus-chat.c      |   11 ++++++
 src/libsystemd-bus/test-bus-signature.c |   11 ++++++
 6 files changed, 101 insertions(+), 65 deletions(-)

New commits:
commit 2bf938c1913b2ba9644cc113de8dc30dd10abbd4
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Mar 22 02:20:39 2013 +0100

    bus: fix uninitialized variable

diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c
index 4bfbd4c..9408806 100644
--- a/src/libsystemd-bus/sd-bus.c
+++ b/src/libsystemd-bus/sd-bus.c
@@ -1035,7 +1035,7 @@ static int dispatch_wqueue(sd_bus *bus) {
 }
 
 static int dispatch_rqueue(sd_bus *bus, sd_bus_message **m) {
-        sd_bus_message *z;
+        sd_bus_message *z = NULL;
         int r, ret = 0;
 
         assert(bus);

commit dafb75912a65e72c3989143f79367a652323a69f
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Mar 22 02:20:21 2013 +0100

    bus: validate the hello response properly

diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c
index 6a6d43f..4bfbd4c 100644
--- a/src/libsystemd-bus/sd-bus.c
+++ b/src/libsystemd-bus/sd-bus.c
@@ -104,16 +104,19 @@ static int hello_callback(sd_bus *bus, int error, sd_bus_message *reply, void *u
 
         assert(reply);
 
-        bus->state = BUS_RUNNING;
-
         r = sd_bus_message_read(reply, "s", &s);
         if (r < 0)
                 return r;
 
+        if (!service_name_is_valid(s) || s[0] != ':')
+                return -EBADMSG;
+
         bus->unique_name = strdup(s);
         if (!bus->unique_name)
                 return -ENOMEM;
 
+        bus->state = BUS_RUNNING;
+
         return 1;
 }
 

commit 813a4f93750be40eff13f127dfef8364642a13bc
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Mar 22 02:19:49 2013 +0100

    bus: properly verify recursion depth of signatures

diff --git a/src/libsystemd-bus/bus-signature.c b/src/libsystemd-bus/bus-signature.c
index db95c88..a92b712 100644
--- a/src/libsystemd-bus/bus-signature.c
+++ b/src/libsystemd-bus/bus-signature.c
@@ -27,6 +27,8 @@
 static int signature_element_length_internal(
                 const char *s,
                 bool allow_dict_entry,
+                unsigned array_depth,
+                unsigned struct_depth,
                 size_t *l) {
 
         int r;
@@ -41,7 +43,10 @@ static int signature_element_length_internal(
         if (*s == SD_BUS_TYPE_ARRAY) {
                 size_t t;
 
-                r = signature_element_length_internal(s + 1, true, &t);
+                if (array_depth >= 32)
+                        return -EINVAL;
+
+                r = signature_element_length_internal(s + 1, true, array_depth+1, struct_depth, &t);
                 if (r < 0)
                         return r;
 
@@ -52,10 +57,13 @@ static int signature_element_length_internal(
         if (*s == SD_BUS_TYPE_STRUCT_BEGIN) {
                 const char *p = s + 1;
 
+                if (struct_depth >= 32)
+                        return -EINVAL;
+
                 while (*p != SD_BUS_TYPE_STRUCT_END) {
                         size_t t;
 
-                        r = signature_element_length_internal(p, false, &t);
+                        r = signature_element_length_internal(p, false, array_depth, struct_depth+1, &t);
                         if (r < 0)
                                 return r;
 
@@ -70,13 +78,16 @@ static int signature_element_length_internal(
                 const char *p = s + 1;
                 unsigned n = 0;
 
+                if (struct_depth >= 32)
+                        return -EINVAL;
+
                 while (*p != SD_BUS_TYPE_DICT_ENTRY_END) {
                         size_t t;
 
                         if (n == 0 && !bus_type_is_basic(*p))
                                 return -EINVAL;
 
-                        r = signature_element_length_internal(p, false, &t);
+                        r = signature_element_length_internal(p, false, array_depth, struct_depth+1, &t);
                         if (r < 0)
                                 return r;
 
@@ -94,6 +105,11 @@ static int signature_element_length_internal(
         return -EINVAL;
 }
 
+
+int signature_element_length(const char *s, size_t *l) {
+        return signature_element_length_internal(s, true, 0, 0, l);
+}
+
 bool signature_is_single(const char *s) {
         int r;
         size_t t;
@@ -126,7 +142,7 @@ bool signature_is_valid(const char *s, bool allow_dict_entry) {
         while (*p) {
                 size_t t;
 
-                r = signature_element_length_internal(p, allow_dict_entry, &t);
+                r = signature_element_length_internal(p, allow_dict_entry, 0, 0, &t);
                 if (r < 0)
                         return false;
 
@@ -135,7 +151,3 @@ bool signature_is_valid(const char *s, bool allow_dict_entry) {
 
         return p - s <= 255;
 }
-
-int signature_element_length(const char *s, size_t *l) {
-        return signature_element_length_internal(s, true, l);
-}
diff --git a/src/libsystemd-bus/test-bus-signature.c b/src/libsystemd-bus/test-bus-signature.c
index 4310d62..5bc4310 100644
--- a/src/libsystemd-bus/test-bus-signature.c
+++ b/src/libsystemd-bus/test-bus-signature.c
@@ -70,5 +70,16 @@ int main(int argc, char *argv[]) {
 
         assert_se(signature_is_valid("sssusa(uuubbba(uu)uuuu)a{u(uuuvas)}", false));
 
+        assert_se(!signature_is_valid("a", false));
+        assert_se(signature_is_valid("as", false));
+        assert_se(signature_is_valid("aas", false));
+        assert_se(signature_is_valid("aaas", false));
+        assert_se(signature_is_valid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaad", false));
+        assert_se(signature_is_valid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaas", false));
+        assert_se(!signature_is_valid("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaau", false));
+
+        assert_se(signature_is_valid("(((((((((((((((((((((((((((((((())))))))))))))))))))))))))))))))", false));
+        assert_se(!signature_is_valid("((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))", false));
+
         return 0;
 }

commit d728d708c3ccfcb34f6d7673f7855fbf0c10aeec
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Mar 22 01:49:56 2013 +0100

    bus: rework synchronization logic
    
    Instead of allowing certain actions fail during authentication and
    connection setup, implicitly synchronize on the connection to be set up
    completely before returning.

diff --git a/src/libsystemd-bus/sd-bus.c b/src/libsystemd-bus/sd-bus.c
index 049bd35..6a6d43f 100644
--- a/src/libsystemd-bus/sd-bus.c
+++ b/src/libsystemd-bus/sd-bus.c
@@ -35,6 +35,7 @@
 #include "bus-message.h"
 #include "bus-type.h"
 
+static int ensure_running(sd_bus *bus);
 static int bus_poll(sd_bus *bus, bool need_more, uint64_t timeout_usec);
 
 static void bus_free(sd_bus *b) {
@@ -778,27 +779,37 @@ int sd_bus_is_open(sd_bus *bus) {
         return bus->fd >= 0;
 }
 
-int sd_bus_is_running(sd_bus *bus) {
+int sd_bus_can_send(sd_bus *bus, char type) {
+        int r;
+
         if (!bus)
                 return -EINVAL;
 
-        if (bus->fd < 0)
-                return -ENOTCONN;
+        if (type == SD_BUS_TYPE_UNIX_FD) {
+                r = ensure_running(bus);
+                if (r < 0)
+                        return r;
 
-        return bus->state == BUS_RUNNING;
+                return bus->can_fds;
+        }
+
+        return bus_type_is_valid(type);
 }
 
-int sd_bus_can_send(sd_bus *bus, char type) {
+int sd_bus_get_peer(sd_bus *bus, sd_id128_t *peer) {
+        int r;
 
         if (!bus)
                 return -EINVAL;
-        if (bus->state != BUS_RUNNING && bus->state != BUS_HELLO)
-                return -EAGAIN;
+        if (!peer)
+                return -EINVAL;
 
-        if (type == SD_BUS_TYPE_UNIX_FD)
-                return bus->can_fds;
+        r = ensure_running(bus);
+        if (r < 0)
+                return r;
 
-        return bus_type_is_valid(type);
+        *peer = bus->peer;
+        return 0;
 }
 
 static int bus_seal_message(sd_bus *b, sd_bus_message *m) {
@@ -1243,22 +1254,15 @@ static int ensure_running(sd_bus *bus) {
 
         assert(bus);
 
-        r = sd_bus_is_running(bus);
-        if (r != 0)
-                return r;
+        if (bus->state == BUS_RUNNING)
+                return 1;
 
         for (;;) {
-                int k;
-
                 r = sd_bus_process(bus, NULL);
-
                 if (r < 0)
                         return r;
-
-                k = sd_bus_is_running(bus);
-                if (k != 0)
-                        return k;
-
+                if (bus->state == BUS_RUNNING)
+                        return 1;
                 if (r > 0)
                         continue;
 
diff --git a/src/libsystemd-bus/sd-bus.h b/src/libsystemd-bus/sd-bus.h
index 3ea4acc..adc7f8e 100644
--- a/src/libsystemd-bus/sd-bus.h
+++ b/src/libsystemd-bus/sd-bus.h
@@ -35,8 +35,9 @@
  * - always verify container depth
  * - merge busctl into systemctl or so?
  * - add object handlers
- * - verify object paths
  * - implicitly add stub introspection calls
+ * - implement unix exec protocol
+ * - server side
  */
 
 typedef struct sd_bus sd_bus;
@@ -62,8 +63,8 @@ sd_bus *sd_bus_ref(sd_bus *bus);
 sd_bus *sd_bus_unref(sd_bus *bus);
 
 int sd_bus_is_open(sd_bus *bus);
-int sd_bus_is_running(sd_bus *bus);
 int sd_bus_can_send(sd_bus *bus, char type);
+int sd_bus_get_peer(sd_bus *bus, sd_id128_t *peer);
 
 int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *serial);
 int sd_bus_send_with_reply(sd_bus *bus, sd_bus_message *m, sd_message_handler_t callback, void *userdata, uint64_t usec, uint64_t *serial);
diff --git a/src/libsystemd-bus/test-bus-chat.c b/src/libsystemd-bus/test-bus-chat.c
index d8677cc..5f533cc 100644
--- a/src/libsystemd-bus/test-bus-chat.c
+++ b/src/libsystemd-bus/test-bus-chat.c
@@ -33,6 +33,7 @@
 
 static int server_init(sd_bus **_bus) {
         sd_bus *bus = NULL;
+        sd_id128_t id;
         int r;
 
         assert(_bus);
@@ -43,6 +44,16 @@ static int server_init(sd_bus **_bus) {
                 goto fail;
         }
 
+        r = sd_bus_get_peer(bus, &id);
+        if (r < 0) {
+                log_error("Failed to get peer ID: %s", strerror(-r));
+                goto fail;
+        }
+
+        log_info("Peer ID is " SD_ID128_FORMAT_STR ".", SD_ID128_FORMAT_VAL(id));
+        log_info("Can send file handles: %i", sd_bus_can_send(bus, 'h'));
+        log_info("Unique ID: %s", strna(sd_bus_get_unique_name(bus)));
+
         r = sd_bus_request_name(bus, "org.freedesktop.systemd.test", 0);
         if (r < 0) {
                 log_error("Failed to acquire name: %s", strerror(-r));

commit 9f26c90cb50c45d4549c4dd569917b4ac143b94d
Author: Lennart Poettering <lennart at poettering.net>
Date:   Fri Mar 22 01:49:13 2013 +0100

    bus: reuse more code

diff --git a/src/libsystemd-bus/bus-message.c b/src/libsystemd-bus/bus-message.c
index a229625..ec98de3 100644
--- a/src/libsystemd-bus/bus-message.c
+++ b/src/libsystemd-bus/bus-message.c
@@ -2121,24 +2121,44 @@ static int message_peek_fields(
         return buffer_peek(m->fields, BUS_MESSAGE_FIELDS_SIZE(m), rindex, align, nbytes, ret);
 }
 
+static int message_peek_field_uint32(
+                sd_bus_message *m,
+                size_t *ri,
+                uint32_t *ret) {
+
+        int r;
+        void *q;
+
+        assert(m);
+        assert(ri);
+
+        r = message_peek_fields(m, ri, 4, 4, &q);
+        if (r < 0)
+                return r;
+
+        if (ret)
+                *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
+
+        return 0;
+}
+
 static int message_peek_field_string(
                 sd_bus_message *m,
                 bool (*validate)(const char *p),
                 size_t *ri,
                 const char **ret) {
 
-        size_t l;
+        uint32_t l;
         int r;
         void *q;
 
         assert(m);
         assert(ri);
 
-        r = message_peek_fields(m, ri, 4, 4, &q);
+        r = message_peek_field_uint32(m, ri, &l);
         if (r < 0)
                 return r;
 
-        l = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
         r = message_peek_fields(m, ri, 1, l+1, &q);
         if (r < 0)
                 return r;
@@ -2190,27 +2210,6 @@ static int message_peek_field_signature(
         return 0;
 }
 
-static int message_peek_field_uint32(
-                sd_bus_message *m,
-                size_t *ri,
-                uint32_t *ret) {
-
-        int r;
-        void *q;
-
-        assert(m);
-        assert(ri);
-
-        r = message_peek_fields(m, ri, 4, 4, &q);
-        if (r < 0)
-                return r;
-
-        if (ret)
-                *ret = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
-
-        return 0;
-}
-
 static int message_skip_fields(
                 sd_bus_message *m,
                 size_t *ri,
@@ -2228,7 +2227,6 @@ static int message_skip_fields(
 
         for (;;) {
                 char t;
-                void *q;
                 size_t l;
 
                 if (array_size != (uint32_t) -1 &&
@@ -2284,7 +2282,7 @@ static int message_skip_fields(
                         assert(l >= 1);
                         {
                                 char sig[l-1], *s;
-                                size_t nas;
+                                uint32_t nas;
                                 int alignment;
 
                                 strncpy(sig, *signature + 1, l-1);
@@ -2294,11 +2292,9 @@ static int message_skip_fields(
                                 if (alignment < 0)
                                         return alignment;
 
-                                r = message_peek_fields(m, ri, 4, 4, &q);
+                                r = message_peek_field_uint32(m, ri, &nas);
                                 if (r < 0)
                                         return r;
-
-                                nas = BUS_MESSAGE_BSWAP32(m, *(uint32_t*) q);
                                 if (nas > BUS_ARRAY_MAX_SIZE)
                                         return -EBADMSG;
 
@@ -2432,8 +2428,6 @@ static int message_parse_fields(sd_bus_message *m) {
 
                         free(m->root_container.signature);
                         m->root_container.signature = c;
-
-                        r = 0;
                         break;
                 }
 



More information about the systemd-commits mailing list