* Special-purpose connections are not allowed to be addressed
* via their unique IDs.
*/
- if (conn_dst->flags & (KDBUS_HELLO_ACTIVATOR |
- KDBUS_HELLO_MONITOR)) {
+ if (conn_dst->type != KDBUS_CONN_CONNECTED) {
ret = -ENXIO;
goto exit_unref;
}
return -EBUSY;
}
- conn->disconnected = true;
+ conn->type = KDBUS_CONN_DISCONNECTED;
mutex_unlock(&conn->lock);
cancel_delayed_work_sync(&conn->work);
*/
bool kdbus_conn_active(const struct kdbus_conn *conn)
{
- return !conn->disconnected;
+ return conn->type != KDBUS_CONN_DISCONNECTED;
}
static void __kdbus_conn_free(struct kref *kref)
}
}
+ if (is_activator)
+ conn->type = KDBUS_CONN_ACTIVATOR;
+ else if (is_policy_holder)
+ conn->type = KDBUS_CONN_POLICY_HOLDER;
+ else if (is_monitor)
+ conn->type = KDBUS_CONN_MONITOR;
+ else
+ conn->type = KDBUS_CONN_CONNECTED;
+
kref_init(&conn->kref);
mutex_init(&conn->lock);
INIT_LIST_HEAD(&conn->msg_list);
switch (cmd) {
case KDBUS_CMD_BYEBYE:
+ if (conn->type != KDBUS_CONN_CONNECTED) {
+ ret = -EPERM;
+ break;
+ }
+
ret = kdbus_conn_disconnect(conn, true);
break;
case KDBUS_CMD_NAME_ACQUIRE:
/* acquire a well-known name */
+ if (conn->type != KDBUS_CONN_CONNECTED) {
+ ret = -EPERM;
+ break;
+ }
+
ret = kdbus_memdup_user(buf, &p, &size,
sizeof(struct kdbus_cmd_name),
sizeof(struct kdbus_cmd_name) +
case KDBUS_CMD_NAME_RELEASE:
/* release a well-known name */
+ if (conn->type != KDBUS_CONN_CONNECTED) {
+ ret = -EPERM;
+ break;
+ }
+
ret = kdbus_memdup_user(buf, &p, NULL,
sizeof(struct kdbus_cmd_name),
sizeof(struct kdbus_cmd_name) +
case KDBUS_CMD_CONN_UPDATE:
/* update the properties of a connection */
+
+ if (conn->type != KDBUS_CONN_CONNECTED) {
+ ret = -EPERM;
+ break;
+ }
+
ret = kdbus_memdup_user(buf, &p, NULL,
sizeof(struct kdbus_cmd_update),
sizeof(struct kdbus_cmd_update) +
case KDBUS_CMD_MATCH_ADD:
/* subscribe to/filter for broadcast messages */
+
+ if (conn->type != KDBUS_CONN_CONNECTED &&
+ conn->type != KDBUS_CONN_MONITOR) {
+ ret = -EPERM;
+ break;
+ }
+
ret = kdbus_memdup_user(buf, &p, NULL,
sizeof(struct kdbus_cmd_match),
sizeof(struct kdbus_cmd_match) +
case KDBUS_CMD_MATCH_REMOVE:
/* unsubscribe from broadcast messages */
+
+ if (conn->type != KDBUS_CONN_CONNECTED &&
+ conn->type != KDBUS_CONN_MONITOR) {
+ ret = -EPERM;
+ break;
+ }
+
ret = kdbus_memdup_user(buf, &p, NULL,
sizeof(struct kdbus_cmd_match),
sizeof(struct kdbus_cmd_match));
/* submit a message which will be queued in the receiver */
struct kdbus_kmsg *kmsg = NULL;
- if (handle->conn->flags & KDBUS_HELLO_ACTIVATOR) {
+ if (conn->type != KDBUS_CONN_CONNECTED) {
ret = -EPERM;
break;
}
case KDBUS_CMD_MSG_RECV: {
struct kdbus_cmd_recv cmd;
+ if (conn->type != KDBUS_CONN_CONNECTED &&
+ conn->type != KDBUS_CONN_MONITOR) {
+ ret = -EPERM;
+ break;
+ }
+
if (!KDBUS_IS_ALIGNED8((uintptr_t)buf))
return -EFAULT;
case KDBUS_CMD_MSG_CANCEL: {
u64 cookie;
+ if (conn->type != KDBUS_CONN_CONNECTED) {
+ ret = -EPERM;
+ break;
+ }
+
if (!KDBUS_IS_ALIGNED8((uintptr_t)buf))
return -EFAULT;
u64 off;
struct kdbus_pool_slice *slice;
+ if (conn->type != KDBUS_CONN_CONNECTED &&
+ conn->type != KDBUS_CONN_MONITOR) {
+ ret = -EPERM;
+ break;
+ }
+
if (!KDBUS_IS_ALIGNED8((uintptr_t)buf))
return -EFAULT;