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(&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

--
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

Reply via email to