return 0;
}
- if (msg->dst_id == KDBUS_DST_ID_NAME) {
- /* unicast message to well-known name */
- BUG_ON(!kmsg->dst_name);
-
+ if (kmsg->dst_name) {
name_entry = kdbus_name_lock(bus->name_registry,
kmsg->dst_name);
if (!name_entry)
return -ESRCH;
+ /*
+ * If both a name and a connection ID are given as destination
+ * of a message, check that the currently owning connection of
+ * the name matches the specified ID.
+ * This way, we allow userspace to send the message to a
+ * specific connection by ID only if the connection currently
+ * owns the given name.
+ */
+ if (msg->dst_id != KDBUS_DST_ID_NAME &&
+ msg->dst_id != name_entry->conn->id) {
+ ret = -EREMCHG;
+ goto exit_name_unlock;
+ }
+
if (!name_entry->conn && name_entry->activator)
conn_dst = kdbus_conn_ref(name_entry->activator);
else
exit_unref:
kdbus_conn_unref(conn_dst);
+exit_name_unlock:
kdbus_name_unlock(bus->name_registry, name_entry);
return ret;
Well-known name to send this message to. Required if dst_id is set
to KDBUS_DST_ID_NAME. If a connection holding the given name can't
be found, -ESRCH is returned.
+ For messages to a unique name (ID), this item is optional. If present,
+ the kernel will make sure the name owner matches the given unique name.
+ This allows userspace tie the message sending to the condition that a
+ name is currently owned by a certain unique name.
};
The message will be augmented by the requested metadata items when queued into
answering
-ECANCELED A synchronous message sending was cancelled
-ENOBUFS Too many pending messages on the receiver side
+ -EREMCHG Both a well-known name and a unique name (ID) was given, but
+ the name is not currently owned by that connection.
For KDBUS_CMD_MSG_RECV: