]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/libsystemd/sd-bus/bus-objects.c
tree-wide: define iterator inside of the macro
[thirdparty/systemd.git] / src / libsystemd / sd-bus / bus-objects.c
index d18c5781775c762245347fe54747f70814cf9fc0..33284d7301e8ba62f2b5bd44491651f7733a9128 100644 (file)
@@ -56,12 +56,18 @@ static int node_vtable_get_userdata(
 static void *vtable_method_convert_userdata(const sd_bus_vtable *p, void *u) {
         assert(p);
 
+        if (!u || FLAGS_SET(p->flags, SD_BUS_VTABLE_ABSOLUTE_OFFSET))
+                return SIZE_TO_PTR(p->x.method.offset); /* don't add offset on NULL, to make ubsan happy */
+
         return (uint8_t*) u + p->x.method.offset;
 }
 
 static void *vtable_property_convert_userdata(const sd_bus_vtable *p, void *u) {
         assert(p);
 
+        if (!u || FLAGS_SET(p->flags, SD_BUS_VTABLE_ABSOLUTE_OFFSET))
+                return SIZE_TO_PTR(p->x.property.offset); /* as above */
+
         return (uint8_t*) u + p->x.property.offset;
 }
 
@@ -353,6 +359,12 @@ static int method_callbacks_run(
         if (require_fallback && !c->parent->is_fallback)
                 return 0;
 
+        if (FLAGS_SET(c->vtable->flags, SD_BUS_VTABLE_SENSITIVE)) {
+                r = sd_bus_message_sensitive(m);
+                if (r < 0)
+                        return r;
+        }
+
         r = check_access(bus, m, c, &error);
         if (r < 0)
                 return bus_maybe_reply_error(m, r, &error);
@@ -577,6 +589,12 @@ static int property_get_set_callbacks_run(
         if (require_fallback && !c->parent->is_fallback)
                 return 0;
 
+        if (FLAGS_SET(c->vtable->flags, SD_BUS_VTABLE_SENSITIVE)) {
+                r = sd_bus_message_sensitive(m);
+                if (r < 0)
+                        return r;
+        }
+
         r = vtable_property_get_userdata(bus, m->path, c, &u, &error);
         if (r <= 0)
                 return bus_maybe_reply_error(m, r, &error);
@@ -591,6 +609,12 @@ static int property_get_set_callbacks_run(
         if (r < 0)
                 return r;
 
+        if (FLAGS_SET(c->vtable->flags, SD_BUS_VTABLE_SENSITIVE)) {
+                r = sd_bus_message_sensitive(reply);
+                if (r < 0)
+                        return r;
+        }
+
         if (is_get) {
                 /* Note that we do not protect against reexecution
                  * here (using the last_iteration check, see below),
@@ -692,6 +716,12 @@ static int vtable_append_one_property(
         assert(c);
         assert(v);
 
+        if (FLAGS_SET(c->vtable->flags, SD_BUS_VTABLE_SENSITIVE)) {
+                r = sd_bus_message_sensitive(reply);
+                if (r < 0)
+                        return r;
+        }
+
         r = sd_bus_message_open_container(reply, 'e', "sv");
         if (r < 0)
                 return r;
@@ -750,9 +780,18 @@ static int vtable_append_all_properties(
                 if (v->flags & SD_BUS_VTABLE_HIDDEN)
                         continue;
 
+                /* Let's not include properties marked as "explicit" in any message that contains a generic
+                 * dump of properties, but only in those generated as a response to an explicit request. */
                 if (v->flags & SD_BUS_VTABLE_PROPERTY_EXPLICIT)
                         continue;
 
+                /* Let's not include properties marked only for invalidation on change (i.e. in contrast to
+                 * those whose new values are included in PropertiesChanges message) in any signals. This is
+                 * useful to ensure they aren't included in InterfacesAdded messages. */
+                if (reply->header->type != SD_BUS_MESSAGE_METHOD_RETURN &&
+                    FLAGS_SET(v->flags, SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION))
+                        continue;
+
                 r = vtable_append_one_property(bus, reply, path, c, v, userdata, error);
                 if (r < 0)
                         return r;
@@ -788,10 +827,10 @@ static int property_get_all_callbacks_run(
         if (r < 0)
                 return r;
 
-        found_interface = !iface ||
-                streq(iface, "org.freedesktop.DBus.Properties") ||
-                streq(iface, "org.freedesktop.DBus.Peer") ||
-                streq(iface, "org.freedesktop.DBus.Introspectable");
+        found_interface = !iface || STR_IN_SET(iface,
+                                               "org.freedesktop.DBus.Properties",
+                                               "org.freedesktop.DBus.Peer",
+                                               "org.freedesktop.DBus.Introspectable");
 
         LIST_FOREACH(vtables, c, first) {
                 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
@@ -900,7 +939,6 @@ int introspect_path(
                 sd_bus_error *error) {
 
         _cleanup_set_free_free_ Set *s = NULL;
-        const char *previous_interface = NULL;
         _cleanup_(introspect_free) struct introspect intro = {};
         struct node_vtable *c;
         bool empty;
@@ -945,23 +983,11 @@ int introspect_path(
                 if (c->vtable[0].flags & SD_BUS_VTABLE_HIDDEN)
                         continue;
 
-                if (!streq_ptr(previous_interface, c->interface)) {
-                        if (previous_interface)
-                                fputs(" </interface>\n", intro.f);
-
-                        fprintf(intro.f, " <interface name=\"%s\">\n", c->interface);
-                }
-
-                r = introspect_write_interface(&intro, c->vtable);
+                r = introspect_write_interface(&intro, c->interface, c->vtable);
                 if (r < 0)
                         return r;
-
-                previous_interface = c->interface;
         }
 
-        if (previous_interface)
-                fputs(" </interface>\n", intro.f);
-
         if (empty) {
                 /* Nothing?, let's see if we exist at all, and if not
                  * refuse to do anything */
@@ -1209,7 +1235,6 @@ static int process_get_managed_objects(
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
         _cleanup_set_free_free_ Set *s = NULL;
-        Iterator i;
         char *path;
         int r;
 
@@ -1239,7 +1264,7 @@ static int process_get_managed_objects(
         if (r < 0)
                 return r;
 
-        SET_FOREACH(path, s, i) {
+        SET_FOREACH(path, s) {
                 r = object_manager_serialize_path_and_fallbacks(bus, reply, path, &error);
                 if (r < 0)
                         return bus_maybe_reply_error(m, r, &error);
@@ -1437,16 +1462,22 @@ int bus_process_object(sd_bus *bus, sd_bus_message *m) {
                 return 0;
 
         if (sd_bus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "Get") ||
-            sd_bus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "Set"))
+            sd_bus_message_is_method_call(m, "org.freedesktop.DBus.Properties", "Set")) {
+                const char *interface = NULL, *property = NULL;
+
+                (void) sd_bus_message_rewind(m, true);
+                (void) sd_bus_message_read_basic(m, 's', &interface);
+                (void) sd_bus_message_read_basic(m, 's', &property);
+
                 r = sd_bus_reply_method_errorf(
                                 m,
                                 SD_BUS_ERROR_UNKNOWN_PROPERTY,
-                                "Unknown property or interface.");
-        else
+                                "Unknown interface %s or property %s.", strnull(interface), strnull(property));
+        else
                 r = sd_bus_reply_method_errorf(
                                 m,
                                 SD_BUS_ERROR_UNKNOWN_METHOD,
-                                "Unknown method '%s' or interface '%s'.", m->member, m->interface);
+                                "Unknown method %s or interface %s.", m->member, m->interface);
 
         if (r < 0)
                 return r;