kdbus: use LSM hooks in kdbus code
authorPaul Osmialowski <p.osmialowsk@samsung.com>
Tue, 26 May 2015 10:00:33 +0000 (12:00 +0200)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Mon, 4 Apr 2016 01:12:42 +0000 (10:12 +0900)
Originates from:

https://github.com/lmctl/kdbus.git (branch: kdbus-lsm-v4.for-systemd-v212)
commit: aa0885489d19be92fa41c6f0a71df28763228a40

Change-Id: Ibcba82b35d22846c2593a42a0c66feda6a115a0f
Signed-off-by: Karol Lewandowski <k.lewandowsk@samsung.com>
Signed-off-by: Paul Osmialowski <p.osmialowsk@samsung.com>
ipc/kdbus/connection.c
ipc/kdbus/connection.h
ipc/kdbus/queue.c

index 424bbdfe3acc52ae59d753806e1979020ee72e4a..b3b081c272976f21663daafb694950d9f58158ad 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/slab.h>
 #include <linux/syscalls.h>
 #include <linux/uio.h>
+#include <linux/security.h>
 
 #include "bus.h"
 #include "connection.h"
@@ -222,6 +223,10 @@ static struct kdbus_conn *kdbus_conn_new(struct kdbus_ep *ep, bool privileged,
                }
        }
 
+       ret = security_kdbus_conn_alloc(conn);
+       if (ret)
+               goto exit_unref;
+
        if (atomic_inc_return(&conn->user->connections) > KDBUS_USER_MAX_CONN) {
                /* decremented by destructor as conn->user is valid */
                ret = -EMFILE;
@@ -276,6 +281,7 @@ static void __kdbus_conn_free(struct kref *kref)
        kdbus_pool_free(conn->pool);
        kdbus_ep_unref(conn->ep);
        put_cred(conn->cred);
+       security_kdbus_conn_free(conn);
        kfree(conn->description);
        kfree(conn->quota);
        kfree(conn);
@@ -1115,6 +1121,10 @@ static int kdbus_conn_reply(struct kdbus_conn *src, struct kdbus_kmsg *kmsg)
        if (ret < 0)
                goto exit;
 
+       ret = security_kdbus_talk(src, dst);
+       if (ret)
+               goto exit;
+
        mutex_lock(&dst->lock);
        reply = kdbus_reply_find(src, dst, kmsg->msg.cookie_reply);
        if (reply) {
@@ -1204,6 +1214,10 @@ static struct kdbus_reply *kdbus_conn_call(struct kdbus_conn *src,
        if (ret < 0)
                goto exit;
 
+       ret = security_kdbus_talk(src, dst);
+       if (ret)
+               goto exit;
+
        /* Disable internal kdbus policy - possibilities of connections to own,
         * see and talk to well-known names are restricted by LSM hooks
        if (!kdbus_conn_policy_talk(src, current_cred(), dst)) {
@@ -1277,6 +1291,10 @@ static int kdbus_conn_unicast(struct kdbus_conn *src, struct kdbus_kmsg *kmsg)
        if (ret < 0)
                goto exit;
 
+       ret = security_kdbus_talk(src, dst);
+       if (ret)
+               goto exit;
+
        if (is_signal) {
                /* like broadcasts we eavesdrop even if the msg is dropped */
                kdbus_bus_eavesdrop(bus, src, kmsg);
index d1ffe909cb31e1a67bd7fb1cf85dbcc6aa2e04a8..4a5c1205b6d36b9441009593125594d117986730 100644 (file)
@@ -73,6 +73,7 @@ struct kdbus_kmsg;
  * @names_queue_list:  Well-known names this connection waits for
  * @privileged:                Whether this connection is privileged on the bus
  * @faked_meta:                Whether the metadata was faked on HELLO
+ * @security:          LSM security blob
  */
 struct kdbus_conn {
        struct kref kref;
@@ -113,6 +114,10 @@ struct kdbus_conn {
 
        bool privileged:1;
        bool faked_meta:1;
+
+#ifdef CONFIG_SECURITY
+       void *security;
+#endif
 };
 
 struct kdbus_conn *kdbus_conn_ref(struct kdbus_conn *conn);
index a449464a39755eb5d7b2e8d9c785fab5f260ea2d..e04aee6786fcc7b2d0340d92a63e9960acfb85fa 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/slab.h>
 #include <linux/syscalls.h>
 #include <linux/uio.h>
+#include <linux/security.h>
 
 #include "util.h"
 #include "domain.h"
@@ -514,12 +515,17 @@ int kdbus_queue_entry_install(struct kdbus_queue_entry *entry,
 
                for (i = 0; i < res->fds_count; i++) {
                        if (install_fds) {
-                               fds[i] = get_unused_fd_flags(O_CLOEXEC);
-                               if (fds[i] >= 0)
-                                       fd_install(fds[i],
-                                                  get_file(res->fds[i]));
-                               else
+                               if (security_file_receive(res->fds[i])) {
+                                       fds[i] = -1;
                                        incomplete_fds = true;
+                               } else {
+                                       fds[i] = get_unused_fd_flags(O_CLOEXEC);
+                                       if (fds[i] >= 0)
+                                               fd_install(fds[i],
+                                                       get_file(res->fds[i]));
+                                       else
+                                               incomplete_fds = true;
+                               }
                        } else {
                                fds[i] = -1;
                        }
@@ -557,13 +563,17 @@ int kdbus_queue_entry_install(struct kdbus_queue_entry *entry,
                m.fd = -1;
 
                if (install_fds) {
-                       m.fd = get_unused_fd_flags(O_CLOEXEC);
-                       if (m.fd < 0) {
-                               m.fd = -1;
+                       if (security_file_receive(d->memfd.file)) {
                                incomplete_fds = true;
                        } else {
-                               fd_install(m.fd,
-                                          get_file(d->memfd.file));
+                               m.fd = get_unused_fd_flags(O_CLOEXEC);
+                               if (m.fd < 0) {
+                                       m.fd = -1;
+                                       incomplete_fds = true;
+                               } else {
+                                       fd_install(m.fd,
+                                               get_file(d->memfd.file));
+                               }
                        }
                }