/**
* struct kdbus_cmd_match - struct to add or remove matches
* @size: The total size of the struct
- * @owner_id: Privileged users may (de)register matches on behalf
- * of other peers
* @cookie: Userspace supplied cookie. When removing, the cookie
* identifies the match to remove
* @items: A list of items for additional information
*/
struct kdbus_cmd_match {
__u64 size;
- __u64 owner_id;
__u64 cookie;
struct kdbus_item items[0];
} __attribute__((aligned(8)));
int kdbus_match_db_add(struct kdbus_conn *conn,
struct kdbus_cmd_match *cmd)
{
- struct kdbus_conn *target_conn = NULL;
struct kdbus_match_entry *entry = NULL;
- struct kdbus_match_db *db;
+ struct kdbus_match_db *db = conn->match_db;
struct kdbus_item *item;
LIST_HEAD(list);
int ret = 0;
- /* privileged users can act on behalf of someone else */
- if (cmd->owner_id == 0)
- cmd->owner_id = conn->id;
- else if (cmd->owner_id != conn->id &&
- !kdbus_bus_uid_is_privileged(conn->bus))
- return -EPERM;
-
- if (cmd->owner_id != 0 && cmd->owner_id != conn->id) {
- target_conn = kdbus_conn_find_peer(conn, cmd->owner_id);
- if (!target_conn) {
- ret = -ENXIO;
- goto exit_free;
- }
-
- db = target_conn->match_db;
- } else {
- db = conn->match_db;
- }
-
entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (!entry) {
ret = -ENOMEM;
}
entry->cookie = cmd->cookie;
-
INIT_LIST_HEAD(&entry->rules_list);
KDBUS_ITEMS_FOREACH(item, cmd->items, KDBUS_ITEMS_SIZE(cmd, items)) {
kdbus_match_entry_free(entry);
exit_free:
- kdbus_conn_unref(target_conn);
-
return ret;
}
int kdbus_match_db_remove(struct kdbus_conn *conn,
struct kdbus_cmd_match *cmd)
{
- struct kdbus_conn *target_conn = NULL;
struct kdbus_match_entry *entry, *tmp;
- struct kdbus_match_db *db;
-
- /* privileged users can act on behalf of someone else */
- if (cmd->owner_id == 0)
- cmd->owner_id = conn->id;
- else if (cmd->owner_id != conn->id &&
- !kdbus_bus_uid_is_privileged(conn->bus))
- return -EPERM;
-
- if (cmd->owner_id != 0 && cmd->owner_id != conn->id) {
- target_conn = kdbus_conn_find_peer(conn, cmd->owner_id);
- if (!target_conn)
- return -ENXIO;
-
- db = target_conn->match_db;
- } else {
- db = conn->match_db;
- }
+ struct kdbus_match_db *db = conn->match_db;
mutex_lock(&db->entries_lock);
list_for_each_entry_safe(entry, tmp, &db->entries_list, list_entry)
kdbus_match_entry_free(entry);
mutex_unlock(&db->entries_lock);
- kdbus_conn_unref(target_conn);
-
return 0;
}
!kdbus_name_is_valid(cmd->name, false))
return -EINVAL;
- /* privileged users can act on behalf of someone else */
- if (cmd->owner_id != 0) {
- struct kdbus_conn *new_conn;
- struct kdbus_bus *bus = conn->bus;
-
- if (!kdbus_bus_uid_is_privileged(bus))
- return -EPERM;
-
- new_conn = kdbus_conn_find_peer(conn, cmd->owner_id);
- if (!new_conn)
- return -ENXIO;
-
- conn = new_conn;
- } else {
- kdbus_conn_ref(conn);
- }
-
if (conn->bus->policy_db) {
ret = kdbus_policy_check_own_access(conn->bus->policy_db,
conn, cmd->name);
if (ret < 0)
- goto exit_unref_conn;
+ goto exit;
}
if (conn->ep->policy_db) {
ret = kdbus_policy_check_own_access(conn->ep->policy_db,
conn, cmd->name);
if (ret < 0)
- goto exit_unref_conn;
+ goto exit;
}
ret = kdbus_name_acquire(reg, conn, cmd->name, &cmd->flags, &e);
-exit_unref_conn:
+exit:
kdbus_notify_flush(conn->bus);
- kdbus_conn_unref(conn);
-
return ret;
}
struct kdbus_conn *conn,
const struct kdbus_cmd_name *cmd)
{
- struct kdbus_bus *bus = conn->bus;
int ret = 0;
if (!kdbus_name_is_valid(cmd->name, false))
return -EINVAL;
- /* privileged users can act on behalf of someone else */
- if (cmd->owner_id > 0) {
- if (!kdbus_bus_uid_is_privileged(bus))
- return -EPERM;
-
- conn = kdbus_conn_find_peer(conn, cmd->owner_id);
- if (!conn)
- return -ENXIO;
- } else {
- kdbus_conn_ref(conn);
- }
-
ret = kdbus_name_release(reg, conn, cmd->name);
kdbus_notify_flush(conn->bus);
- kdbus_conn_unref(conn);
-
return ret;
}