diff options
author | Kay Sievers <kay@vrfy.org> | 2013-05-19 17:55:51 +0200 |
---|---|---|
committer | Kay Sievers <kay@vrfy.org> | 2013-05-19 17:55:51 +0200 |
commit | 69f18e037887dcdf77077e75976e342119509968 (patch) | |
tree | 546a250a7b35b0dd88f10d2c880abc815516ba61 | |
parent | d4ecc535a1abcabbb1b5df2692f325e3dc778988 (diff) | |
download | kdbus-bus-69f18e037887dcdf77077e75976e342119509968.tar.gz kdbus-bus-69f18e037887dcdf77077e75976e342119509968.tar.bz2 kdbus-bus-69f18e037887dcdf77077e75976e342119509968.zip |
match: accept cmd_match->src_id == 0 for "self"
-rw-r--r-- | connection.c | 4 | ||||
-rw-r--r-- | match.c | 29 | ||||
-rw-r--r-- | match.h | 4 |
3 files changed, 26 insertions, 11 deletions
diff --git a/connection.c b/connection.c index 232474b8f6c..d42631b7c9f 100644 --- a/connection.c +++ b/connection.c @@ -1274,7 +1274,7 @@ static long kdbus_conn_ioctl_ep(struct file *file, unsigned int cmd, break; } - ret = kdbus_cmd_match_db_add(conn, buf); + ret = kdbus_match_db_add(conn, buf); break; case KDBUS_CMD_MATCH_REMOVE: @@ -1284,7 +1284,7 @@ static long kdbus_conn_ioctl_ep(struct file *file, unsigned int cmd, break; } - ret = kdbus_cmd_match_db_remove(conn->match_db, buf); + ret = kdbus_match_db_remove(conn, buf); break; case KDBUS_CMD_MONITOR: { @@ -263,8 +263,7 @@ bool kdbus_match_db_match_kmsg(struct kdbus_match_db *db, return kdbus_match_db_match_from_kernel(db, conn_dst, kmsg); } -static -struct kdbus_cmd_match *cmd_match_from_user(void __user *buf) +static struct kdbus_cmd_match *cmd_match_from_user(void __user *buf, bool items) { struct kdbus_cmd_match *cmd_match; u64 size; @@ -275,10 +274,14 @@ struct kdbus_cmd_match *cmd_match_from_user(void __user *buf) if (size < sizeof(*cmd_match) || size > KDBUS_MATCH_MAX_SIZE) return ERR_PTR(-EMSGSIZE); + /* remove does not accept any items */ + if (items && size != sizeof(*cmd_match)) + return ERR_PTR(-EMSGSIZE); + return memdup_user(buf, size); } -int kdbus_cmd_match_db_add(struct kdbus_conn *conn, void __user *buf) +int kdbus_match_db_add(struct kdbus_conn *conn, void __user *buf) { struct kdbus_match_db *db = conn->match_db; struct kdbus_cmd_match *cmd_match; @@ -286,7 +289,7 @@ int kdbus_cmd_match_db_add(struct kdbus_conn *conn, void __user *buf) struct kdbus_match_db_entry *e; int ret = 0; - cmd_match = cmd_match_from_user(buf); + cmd_match = cmd_match_from_user(buf, true); if (IS_ERR(cmd_match)) return PTR_ERR(cmd_match); @@ -298,9 +301,15 @@ int kdbus_cmd_match_db_add(struct kdbus_conn *conn, void __user *buf) INIT_LIST_HEAD(&e->list_entry); INIT_LIST_HEAD(&e->items_list); e->id = cmd_match->id; - e->src_id = cmd_match->src_id; e->cookie = cmd_match->cookie; + /* fill-in connection id, if not given */ + if (cmd_match->src_id == 0) + e->src_id = conn->id; + else + e->src_id = cmd_match->src_id; + //FIXME: limit actions on behalf of others to privileged users + KDBUS_ITEM_FOREACH_VALIDATE(item, cmd_match) { struct kdbus_match_db_entry_item *ei; size_t size; @@ -362,15 +371,21 @@ int kdbus_cmd_match_db_add(struct kdbus_conn *conn, void __user *buf) return ret; } -int kdbus_cmd_match_db_remove(struct kdbus_match_db *db, void __user *buf) +int kdbus_match_db_remove(struct kdbus_conn *conn, void __user *buf) { + struct kdbus_match_db *db = conn->match_db; struct kdbus_cmd_match *cmd_match; struct kdbus_match_db_entry *e, *tmp; - cmd_match = cmd_match_from_user(buf); + cmd_match = cmd_match_from_user(buf, false); if (IS_ERR(cmd_match)) return PTR_ERR(cmd_match); + /* fill-in connection id, if not given */ + if (cmd_match->id == 0) + cmd_match->id = conn->id; + //FIXME: limit actions on behalf of others to privileged users + mutex_lock(&db->entries_lock); list_for_each_entry_safe(e, tmp, &db->entries, list_entry) if (e->cookie == cmd_match->cookie && @@ -25,8 +25,8 @@ struct kdbus_kmsg; struct kdbus_match_db *kdbus_match_db_new(void); void kdbus_match_db_unref(struct kdbus_match_db *db); -int kdbus_cmd_match_db_add(struct kdbus_conn *conn, void __user *buf); -int kdbus_cmd_match_db_remove(struct kdbus_match_db *db, void __user *buf); +int kdbus_match_db_add(struct kdbus_conn *conn, void __user *buf); +int kdbus_match_db_remove(struct kdbus_conn *conn, void __user *buf); bool kdbus_match_db_match_kmsg(struct kdbus_match_db *db, struct kdbus_conn *conn_src, struct kdbus_conn *conn_dst, |