chiark / gitweb /
util: rework strappenda(), and rename it strjoina()
[elogind.git] / src / libsystemd / sd-bus / bus-control.c
index 6a9e9b296ad2df56277b415b9845381e8e946688..ac27df8691d75012597a1eab780a41be98befbb6 100644 (file)
@@ -33,6 +33,7 @@
 #include "bus-control.h"
 #include "bus-bloom.h"
 #include "bus-util.h"
+#include "capability.h"
 #include "cgroup-util.h"
 
 _public_ int sd_bus_get_unique_name(sd_bus *bus, const char **unique) {
@@ -136,6 +137,10 @@ _public_ int sd_bus_request_name(sd_bus *bus, const char *name, uint64_t flags)
         assert_return(service_name_is_valid(name), -EINVAL);
         assert_return(name[0] != ':', -EINVAL);
 
+        /* Don't allow requesting the special driver and local names */
+        if (STR_IN_SET(name, "org.freedesktop.DBus", "org.freedesktop.DBus.Local"))
+                return -EINVAL;
+
         if (!BUS_IS_OPEN(bus->state))
                 return -ENOTCONN;
 
@@ -214,6 +219,10 @@ _public_ int sd_bus_release_name(sd_bus *bus, const char *name) {
         assert_return(service_name_is_valid(name), -EINVAL);
         assert_return(name[0] != ':', -EINVAL);
 
+        /* Don't allow releasing the special driver and local names */
+        if (STR_IN_SET(name, "org.freedesktop.DBus", "org.freedesktop.DBus.Local"))
+                return -EINVAL;
+
         if (!BUS_IS_OPEN(bus->state))
                 return -ENOTCONN;
 
@@ -232,6 +241,7 @@ static int kernel_get_list(sd_bus *bus, uint64_t flags, char ***x) {
 
         /* Caller will free half-constructed list on failure... */
 
+        cmd.size = sizeof(cmd);
         cmd.flags = flags;
 
         r = ioctl(bus->input_fd, KDBUS_CMD_NAME_LIST, &cmd);
@@ -405,11 +415,6 @@ static int bus_populate_creds_from_items(
                                 c->mask |= SD_BUS_CREDS_TID;
                         }
 
-                        if (mask & SD_BUS_CREDS_PID_STARTTIME && item->pids.starttime > 0) {
-                                c->pid_starttime = item->pids.starttime;
-                                c->mask |= SD_BUS_CREDS_PID_STARTTIME;
-                        }
-
                         break;
 
                 case KDBUS_ITEM_CREDS:
@@ -524,8 +529,11 @@ static int bus_populate_creds_from_items(
                              SD_BUS_CREDS_INHERITABLE_CAPS | SD_BUS_CREDS_BOUNDING_CAPS) & mask;
 
                         if (m) {
-                                c->capability_size = item->size - offsetof(struct kdbus_item, caps.caps);
-                                c->capability = memdup(item->caps.caps, c->capability_size);
+                                if (item->caps.last_cap != cap_last_cap() ||
+                                    item->size - offsetof(struct kdbus_item, caps.caps) < DIV_ROUND_UP(item->caps.last_cap, 32U) * 4 * 4)
+                                        return -EBADMSG;
+
+                                c->capability = memdup(item->caps.caps, item->size - offsetof(struct kdbus_item, caps.caps));
                                 if (!c->capability)
                                         return -ENOMEM;
 
@@ -614,6 +622,9 @@ int bus_get_name_creds_kdbus(
         uint64_t id;
         int r;
 
+        if (streq(name, "org.freedesktop.DBus"))
+                return -ENOTSUP;
+
         r = bus_kernel_parse_unique_name(name, &id);
         if (r < 0)
                 return r;
@@ -630,11 +641,8 @@ int bus_get_name_creds_kdbus(
                 memcpy(cmd->items[0].str, name, l);
         }
 
-        cmd->size = size;
-        cmd->flags = attach_flags_to_kdbus(mask);
-
-        /* If augmentation is on, and the bus doesn't didn't allow us
-         * to get the bits we want, then ask for the PID/TID so that we
+        /* If augmentation is on, and the bus didn't provide us
+         * the bits we want, then ask for the PID/TID so that we
          * can read the rest from /proc. */
         if ((mask & SD_BUS_CREDS_AUGMENT) &&
             (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
@@ -644,7 +652,10 @@ int bus_get_name_creds_kdbus(
                      SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
                      SD_BUS_CREDS_SELINUX_CONTEXT|
                      SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)))
-                cmd->flags |= KDBUS_ATTACH_PIDS;
+                mask |= SD_BUS_CREDS_PID;
+
+        cmd->size = size;
+        cmd->flags = attach_flags_to_kdbus(mask);
 
         r = ioctl(bus->input_fd, KDBUS_CMD_CONN_INFO, cmd);
         if (r < 0)
@@ -751,8 +762,7 @@ static int bus_get_name_creds_dbus1(
 
                 if ((mask & SD_BUS_CREDS_PID) ||
                     ((mask & SD_BUS_CREDS_AUGMENT) &&
-                     (mask & (SD_BUS_CREDS_PID_STARTTIME|
-                              SD_BUS_CREDS_EUID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
+                     (mask & (SD_BUS_CREDS_UID|SD_BUS_CREDS_SUID|SD_BUS_CREDS_FSUID|
                               SD_BUS_CREDS_GID|SD_BUS_CREDS_EGID|SD_BUS_CREDS_SGID|SD_BUS_CREDS_FSGID|
                               SD_BUS_CREDS_COMM|SD_BUS_CREDS_EXE|SD_BUS_CREDS_CMDLINE|
                               SD_BUS_CREDS_CGROUP|SD_BUS_CREDS_UNIT|SD_BUS_CREDS_USER_UNIT|SD_BUS_CREDS_SLICE|SD_BUS_CREDS_SESSION|SD_BUS_CREDS_OWNER_UID|
@@ -788,7 +798,7 @@ static int bus_get_name_creds_dbus1(
                         reply = sd_bus_message_unref(reply);
                 }
 
-                if (mask & SD_BUS_CREDS_UID) {
+                if (mask & SD_BUS_CREDS_EUID) {
                         uint32_t u;
 
                         r = sd_bus_call_method(
@@ -808,8 +818,8 @@ static int bus_get_name_creds_dbus1(
                         if (r < 0)
                                 return r;
 
-                        c->uid = u;
-                        c->mask |= SD_BUS_CREDS_UID;
+                        c->euid = u;
+                        c->mask |= SD_BUS_CREDS_EUID;
 
                         reply = sd_bus_message_unref(reply);
                 }
@@ -872,6 +882,9 @@ _public_ int sd_bus_get_name_creds(
         assert_return(service_name_is_valid(name), -EINVAL);
         assert_return(bus->bus_client, -ENODATA);
 
+        if (streq(name, "org.freedesktop.DBus.Local"))
+                return -EINVAL;
+
         if (!BUS_IS_OPEN(bus->state))
                 return -ENOTCONN;
 
@@ -894,8 +907,6 @@ static int bus_get_owner_creds_kdbus(sd_bus *bus, uint64_t mask, sd_bus_creds **
         if (!c)
                 return -ENOMEM;
 
-        cmd.flags = attach_flags_to_kdbus(mask);
-
         /* If augmentation is on, and the bus doesn't didn't allow us
          * to get the bits we want, then ask for the PID/TID so that we
          * can read the rest from /proc. */
@@ -907,7 +918,9 @@ static int bus_get_owner_creds_kdbus(sd_bus *bus, uint64_t mask, sd_bus_creds **
                      SD_BUS_CREDS_EFFECTIVE_CAPS|SD_BUS_CREDS_PERMITTED_CAPS|SD_BUS_CREDS_INHERITABLE_CAPS|SD_BUS_CREDS_BOUNDING_CAPS|
                      SD_BUS_CREDS_SELINUX_CONTEXT|
                      SD_BUS_CREDS_AUDIT_SESSION_ID|SD_BUS_CREDS_AUDIT_LOGIN_UID)))
-                cmd.flags |= KDBUS_ATTACH_PIDS;
+                mask |= SD_BUS_CREDS_PID;
+
+        cmd.flags = attach_flags_to_kdbus(mask);
 
         r = ioctl(bus->input_fd, KDBUS_CMD_BUS_CREATOR_INFO, &cmd);
         if (r < 0)
@@ -948,13 +961,13 @@ static int bus_get_owner_creds_dbus1(sd_bus *bus, uint64_t mask, sd_bus_creds **
                 }
 
                 if (bus->ucred.uid != UID_INVALID) {
-                        c->uid = bus->ucred.uid;
-                        c->mask |= SD_BUS_CREDS_UID & mask;
+                        c->euid = bus->ucred.uid;
+                        c->mask |= SD_BUS_CREDS_EUID & mask;
                 }
 
                 if (bus->ucred.gid != GID_INVALID) {
-                        c->gid = bus->ucred.gid;
-                        c->mask |= SD_BUS_CREDS_GID & mask;
+                        c->egid = bus->ucred.gid;
+                        c->mask |= SD_BUS_CREDS_EGID & mask;
                 }
         }
 
@@ -1180,6 +1193,10 @@ int bus_add_match_internal_kernel(
 
         assert(bus);
 
+        /* Monitor streams don't support matches, make this a NOP */
+        if (bus->hello_flags & KDBUS_HELLO_MONITOR)
+                return 0;
+
         bloom = alloca0(bus->bloom_size);
 
         sz = ALIGN8(offsetof(struct kdbus_cmd_match, items));
@@ -1251,7 +1268,7 @@ int bus_add_match_internal_kernel(
                         if (c->type - BUS_MATCH_ARG < 3)
                                 name_change_arg[c->type - BUS_MATCH_ARG] = c->value_str;
 
-                        snprintf(buf, sizeof(buf), "arg%u", c->type - BUS_MATCH_ARG);
+                        xsprintf(buf, "arg%i", c->type - BUS_MATCH_ARG);
                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
                         using_bloom = true;
                         break;
@@ -1260,7 +1277,7 @@ int bus_add_match_internal_kernel(
                 case BUS_MATCH_ARG_PATH...BUS_MATCH_ARG_PATH_LAST: {
                         char buf[sizeof("arg")-1 + 2 + sizeof("-slash-prefix")];
 
-                        snprintf(buf, sizeof(buf), "arg%u-slash-prefix", c->type - BUS_MATCH_ARG_PATH);
+                        xsprintf(buf, "arg%i-slash-prefix", c->type - BUS_MATCH_ARG_PATH);
                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
                         using_bloom = true;
                         break;
@@ -1269,7 +1286,7 @@ int bus_add_match_internal_kernel(
                 case BUS_MATCH_ARG_NAMESPACE...BUS_MATCH_ARG_NAMESPACE_LAST: {
                         char buf[sizeof("arg")-1 + 2 + sizeof("-dot-prefix")];
 
-                        snprintf(buf, sizeof(buf), "arg%u-dot-prefix", c->type - BUS_MATCH_ARG_NAMESPACE);
+                        xsprintf(buf, "arg%i-dot-prefix", c->type - BUS_MATCH_ARG_NAMESPACE);
                         bloom_add_pair(bloom, bus->bloom_size, bus->bloom_n_hash, buf, c->value_str);
                         using_bloom = true;
                         break;
@@ -1342,7 +1359,7 @@ int bus_add_match_internal_kernel(
 
 #define internal_match(bus, m)                                          \
         ((bus)->hello_flags & KDBUS_HELLO_MONITOR                       \
-         ? (isempty(m) ? "eavesdrop='true'" : strappenda((m), ",eavesdrop='true'")) \
+         ? (isempty(m) ? "eavesdrop='true'" : strjoina((m), ",eavesdrop='true'")) \
          : (m))
 
 static int bus_add_match_internal_dbus1(
@@ -1392,6 +1409,10 @@ int bus_remove_match_internal_kernel(
 
         assert(bus);
 
+        /* Monitor streams don't support matches, make this a NOP */
+        if (bus->hello_flags & KDBUS_HELLO_MONITOR)
+                return 0;
+
         zero(m);
         m.size = offsetof(struct kdbus_cmd_match, items);
         m.cookie = cookie;