summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKay Sievers <kay@vrfy.org>2013-05-19 17:55:51 +0200
committerKay Sievers <kay@vrfy.org>2013-05-19 17:55:51 +0200
commit69f18e037887dcdf77077e75976e342119509968 (patch)
tree546a250a7b35b0dd88f10d2c880abc815516ba61
parentd4ecc535a1abcabbb1b5df2692f325e3dc778988 (diff)
downloadkdbus-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.c4
-rw-r--r--match.c29
-rw-r--r--match.h4
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: {
diff --git a/match.c b/match.c
index 4081babb20c..284d5c64bbd 100644
--- a/match.c
+++ b/match.c
@@ -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 &&
diff --git a/match.h b/match.h
index 64e32241dcc..9838bb3926e 100644
--- a/match.h
+++ b/match.h
@@ -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,