kdbus: make use of new lsm hooks

Started by Karol Lewandowski on Oct 31, 2014

Subsystems (2)

Maintainers (3)

DORMANTno replies

open the first message on its own page

Message details and related content
DANGEROUS:  This version has been compile-tested only!

Signed-off-by: Karol Lewandowski <redacted>
---
 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(&reg->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
Keyboard shortcuts
hback out one level
jnext message in thread / next series-diff position
kprevious message in thread / previous series-diff position
ldrill in
Escclose help / fold thread tree
?toggle this help