From f13b7e7bd8a435a87f72a8b8ca3015047e5912cd Mon Sep 17 00:00:00 2001 From: Paul Osmialowski Date: Tue, 26 May 2015 12:00:33 +0200 Subject: [PATCH] kdbus: use LSM hooks in kdbus code 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 Signed-off-by: Paul Osmialowski --- ipc/kdbus/connection.c | 18 ++++++++++++++++++ ipc/kdbus/connection.h | 5 +++++ ipc/kdbus/queue.c | 30 ++++++++++++++++++++---------- 3 files changed, 43 insertions(+), 10 deletions(-) diff --git a/ipc/kdbus/connection.c b/ipc/kdbus/connection.c index 424bbdfe3acc..b3b081c27297 100644 --- a/ipc/kdbus/connection.c +++ b/ipc/kdbus/connection.c @@ -31,6 +31,7 @@ #include #include #include +#include #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); diff --git a/ipc/kdbus/connection.h b/ipc/kdbus/connection.h index d1ffe909cb31..4a5c1205b6d3 100644 --- a/ipc/kdbus/connection.h +++ b/ipc/kdbus/connection.h @@ -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); diff --git a/ipc/kdbus/queue.c b/ipc/kdbus/queue.c index a449464a3975..e04aee6786fc 100644 --- a/ipc/kdbus/queue.c +++ b/ipc/kdbus/queue.c @@ -28,6 +28,7 @@ #include #include #include +#include #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)); + } } } -- 2.34.1