DANGEROUS: This version has been compile-tested only!
Signed-off-by: Karol Lewandowski <[email protected]>
---
drivers/misc/kdbus/bus.c | 10 +++++++++-
drivers/misc/kdbus/connection.c | 34 +++++++++++++++++++++++++++++++++-
drivers/misc/kdbus/domain.c | 7 +++++++
drivers/misc/kdbus/endpoint.c | 11 +++++++++++
drivers/misc/kdbus/names.c | 9 +++++++++
5 files changed, 69 insertions(+), 2 deletions(-)
diff --git a/drivers/misc/kdbus/bus.c b/drivers/misc/kdbus/bus.c
index 6dcaf22..f9bb177 100644
--- a/drivers/misc/kdbus/bus.c
+++ b/drivers/misc/kdbus/bus.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/random.h>
#include <linux/sched.h>
+#include <linux/security.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
@@ -97,6 +98,7 @@ static void __kdbus_bus_free(struct kref *kref)
kdbus_domain_unref(bus->domain);
kdbus_policy_db_clear(&bus->policy_db);
kdbus_meta_free(bus->meta);
+ security_kdbus_bus_free(bus);
kfree(bus->name);
kfree(bus);
}
@@ -351,9 +353,13 @@ int kdbus_bus_new(struct kdbus_domain *domain,
if (ret < 0)
goto exit_free_name;
+ ret = security_kdbus_bus_alloc(b);
+ if (ret)
+ goto exit_free_reg;
+
ret = kdbus_ep_new(b, "bus", mode, uid, gid, false, &b->ep);
if (ret < 0)
- goto exit_free_reg;
+ goto exit_free_security;
/* link into domain */
mutex_lock(&domain->lock);
@@ -386,6 +392,8 @@ exit_unref_user_unlock:
kdbus_domain_user_unref(b->user);
kdbus_ep_disconnect(b->ep);
kdbus_ep_unref(b->ep);
+exit_free_security:
+ security_kdbus_bus_free(b);
exit_free_reg:
kdbus_name_registry_free(b->name_registry);
exit_free_name:
diff --git a/drivers/misc/kdbus/connection.c b/drivers/misc/kdbus/connection.c
index 5b1f3ed..96c5c52 100644
--- a/drivers/misc/kdbus/connection.c
+++ b/drivers/misc/kdbus/connection.c
@@ -27,6 +27,7 @@
#include <linux/sched.h>
#include <linux/shmem_fs.h>
#include <linux/sizes.h>
+#include <linux/security.h>
#include <linux/slab.h>
#include <linux/syscalls.h>
@@ -282,6 +283,10 @@ int kdbus_cmd_msg_recv(struct kdbus_conn *conn,
if (recv->offset > 0)
return -EINVAL;
+ ret = security_kdbus_recv(conn, conn->ep->bus);
+ if (ret)
+ return ret;
+
mutex_lock(&conn->lock);
ret = kdbus_queue_entry_peek(&conn->queue, recv->priority,
recv->flags & KDBUS_RECV_USE_PRIORITY,
@@ -460,7 +465,12 @@ static int kdbus_conn_check_access(struct kdbus_ep *ep,
if (allowed)
return 0;
- /* ... otherwise, ask the policy DBs for permission */
+ /* ... consult LSM */
+ ret = security_kdbus_talk(conn_src, conn_dst);
+ if (ret)
+ return ret;
+
+ /* ... finally, ask the policy DBs for permission */
ret = kdbus_ep_policy_check_talk_access(ep, conn_src, conn_dst);
if (ret < 0)
return ret;
@@ -596,6 +606,10 @@ static void kdbus_conn_broadcast(struct kdbus_ep *ep,
* data, even when they did not ask for it.
*/
if (conn_src) {
+ ret = security_kdbus_talk(conn_src, conn_dst);
+ if (ret)
+ continue;
+
/* Check if conn_src is allowed to signal */
ret = kdbus_ep_policy_check_broadcast(conn_dst->ep,
conn_src,
@@ -736,6 +750,10 @@ int kdbus_conn_kmsg_send(struct kdbus_ep *ep,
bool sync = msg->flags & KDBUS_MSG_FLAGS_SYNC_REPLY;
int ret = 0;
+ ret = security_kdbus_send(conn_src, bus);
+ if (ret)
+ return ret;
+
/* assign domain-global message sequence number */
BUG_ON(kmsg->seq > 0);
kmsg->seq = atomic64_inc_return(&bus->domain->msg_seq_last);
@@ -1086,6 +1104,7 @@ static void __kdbus_conn_free(struct kref *kref)
kdbus_ep_unref(conn->ep);
kdbus_bus_unref(conn->bus);
put_cred(conn->cred);
+ security_kdbus_conn_free(conn);
kfree(conn->name);
kfree(conn);
}
@@ -1467,8 +1486,12 @@ int kdbus_conn_new(struct kdbus_ep *ep,
bool is_policy_holder;
bool is_activator;
bool is_monitor;
+ u32 len;
+ u32 sid;
+ char *label;
int ret;
+
BUG_ON(*c);
is_monitor = hello->flags & KDBUS_HELLO_MONITOR;
@@ -1542,6 +1565,9 @@ int kdbus_conn_new(struct kdbus_ep *ep,
return -ENOMEM;
if (is_activator || is_policy_holder) {
+ ret = security_kdbus_ep_setpolicy(bus);
+ if (ret)
+ goto exit_free_conn;
/*
* Policy holders may install one name, and are
* allowed to use wildcards.
@@ -1680,6 +1706,12 @@ int kdbus_conn_new(struct kdbus_ep *ep,
goto exit_unref_user_unlock;
}
+ security_task_getsecid(current, &sid);
+ security_secid_to_secctx(sid, &label, &len);
+ ret = security_kdbus_connect(conn, label, len);
+ if (ret < 0)
+ goto exit_unref_user_unlock;
+
/* link into bus and endpoint */
list_add_tail(&conn->ep_entry, &ep->conn_list);
hash_add(bus->conn_hash, &conn->hentry, conn->id);
diff --git a/drivers/misc/kdbus/domain.c b/drivers/misc/kdbus/domain.c
index eb2ce72..43b77ed 100644
--- a/drivers/misc/kdbus/domain.c
+++ b/drivers/misc/kdbus/domain.c
@@ -18,6 +18,7 @@
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/sizes.h>
+#include <linux/security.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
@@ -156,6 +157,7 @@ static void __kdbus_domain_free(struct device *dev)
idr_destroy(&domain->user_idr);
kfree(domain->name);
kfree(domain->devpath);
+ security_kdbus_domain_free(domain);
kfree(domain);
}
@@ -255,6 +257,10 @@ int kdbus_domain_new(struct kdbus_domain *parent, const
char *name,
if (ret < 0)
goto exit_put;
+ ret = security_kdbus_domain_alloc(d);
+ if (ret)
+ goto exit_put;
+
if (parent) {
/* lock order: parent domain -> domain */
mutex_lock(&parent->lock);
@@ -444,6 +450,7 @@ static void __kdbus_domain_user_free(struct kref *kref)
hash_del(&user->hentry);
mutex_unlock(&user->domain->lock);
+ security_kdbus_domain_free(user->domain);
kdbus_domain_unref(user->domain);
kfree(user);
}
diff --git a/drivers/misc/kdbus/endpoint.c b/drivers/misc/kdbus/endpoint.c
index 8304360..74444c3 100644
--- a/drivers/misc/kdbus/endpoint.c
+++ b/drivers/misc/kdbus/endpoint.c
@@ -17,6 +17,7 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
+#include <linux/security.h>
#include <linux/sizes.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
@@ -197,6 +198,10 @@ int kdbus_ep_new(struct kdbus_bus *bus, const char *name,
if (ret < 0)
goto exit_put;
+ ret = security_kdbus_ep_create(bus);
+ if (ret)
+ goto exit_put;
+
mutex_lock(&bus->lock);
if (bus->disconnected) {
@@ -255,6 +260,12 @@ int kdbus_ep_policy_set(struct kdbus_ep *ep,
const struct kdbus_item *items,
size_t items_size)
{
+ int ret;
+
+ ret = security_kdbus_ep_setpolicy(ep->bus);
+ if (ret)
+ return ret;
+
return kdbus_policy_set(&ep->policy_db, items, items_size, 0, true, ep);
}
diff --git a/drivers/misc/kdbus/names.c b/drivers/misc/kdbus/names.c
index 5f8853c..c13b0fb 100644
--- a/drivers/misc/kdbus/names.c
+++ b/drivers/misc/kdbus/names.c
@@ -22,6 +22,7 @@
#include <linux/mutex.h>
#include <linux/rwsem.h>
#include <linux/sched.h>
+#include <linux/security.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
@@ -492,6 +493,10 @@ int kdbus_name_acquire(struct kdbus_name_registry *reg,
u32 hash;
int ret = 0;
+ ret = security_kdbus_name_acquire(conn, name);
+ if (ret)
+ return ret;
+
/* lock order: domain -> bus -> ep -> names -> conn */
mutex_lock(&conn->bus->lock);
down_write(®->rwlock);
@@ -876,6 +881,10 @@ int kdbus_cmd_name_list(struct kdbus_name_registry *reg,
size_t pos;
int ret;
+ ret = security_kdbus_name_list(conn->bus);
+ if (ret)
+ return ret;
+
policy_db = &conn->ep->policy_db;
/* lock order: domain -> bus -> ep -> names -> conn */
--
2.1.1
--
To unsubscribe from this list: send the line "unsubscribe linux-api" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html