[RFC PATCH v1 02/10] landlock: Add hook on socket_create()
Ivanov Mikhail
ivanov.mikhail1 at huawei-partners.com
Mon Apr 8 09:39:19 UTC 2024
Add hook on socket_create() method. Since it'll be better to have control
over possible socket changes after family-related create() call, hook is
called on socket_post_create(). Handler only checks if the socket type
and family are allowed by domain.
Signed-off-by: Ivanov Mikhail <ivanov.mikhail1 at huawei-partners.com>
Reviewed-by: Konstantin Meskhidze <konstantin.meskhidze at huawei.com>
---
security/landlock/setup.c | 2 ++
security/landlock/socket.c | 72 ++++++++++++++++++++++++++++++++++++++
security/landlock/socket.h | 2 ++
3 files changed, 76 insertions(+)
diff --git a/security/landlock/setup.c b/security/landlock/setup.c
index 28519a45b..fd4e7e8f3 100644
--- a/security/landlock/setup.c
+++ b/security/landlock/setup.c
@@ -14,6 +14,7 @@
#include "cred.h"
#include "fs.h"
#include "net.h"
+#include "socket.h"
#include "setup.h"
#include "task.h"
@@ -37,6 +38,7 @@ static int __init landlock_init(void)
landlock_add_task_hooks();
landlock_add_fs_hooks();
landlock_add_net_hooks();
+ landlock_add_socket_hooks();
landlock_initialized = true;
pr_info("Up and running.\n");
return 0;
diff --git a/security/landlock/socket.c b/security/landlock/socket.c
index 88b4ef3a1..cba584543 100644
--- a/security/landlock/socket.c
+++ b/security/landlock/socket.c
@@ -5,6 +5,10 @@
* Copyright © 2024 Huawei Tech. Co., Ltd.
*/
+#include <linux/net.h>
+#include <net/sock.h>
+
+#include "cred.h"
#include "limits.h"
#include "ruleset.h"
#include "socket.h"
@@ -41,3 +45,71 @@ int landlock_append_socket_rule(struct landlock_ruleset *const ruleset,
return err;
}
+
+static access_mask_t
+get_raw_handled_socket_accesses(const struct landlock_ruleset *const domain)
+{
+ access_mask_t access_dom = 0;
+ size_t layer_level;
+
+ for (layer_level = 0; layer_level < domain->num_layers; layer_level++)
+ access_dom |= landlock_get_socket_access_mask(domain, layer_level);
+ return access_dom;
+}
+
+static const struct landlock_ruleset *get_current_socket_domain(void)
+{
+ const struct landlock_ruleset *const dom =
+ landlock_get_current_domain();
+
+ if (!dom || !get_raw_handled_socket_accesses(dom))
+ return NULL;
+
+ return dom;
+}
+
+static int current_check_access_socket(struct socket *const sock,
+ const access_mask_t access_request)
+{
+ union socket_key socket_key;
+ layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_SOCKET] = {};
+ const struct landlock_rule *rule;
+ access_mask_t handled_access;
+ struct landlock_id id = {
+ .type = LANDLOCK_KEY_SOCKET,
+ };
+ const struct landlock_ruleset *const dom = get_current_socket_domain();
+
+ if (!dom)
+ return 0;
+ if (WARN_ON_ONCE(dom->num_layers < 1))
+ return -EACCES;
+
+ socket_key.content.type = sock->type;
+ socket_key.content.domain = sock->sk->__sk_common.skc_family;
+ id.key.data = socket_key.val;
+
+ rule = landlock_find_rule(dom, id);
+ handled_access = landlock_init_layer_masks(
+ dom, access_request, &layer_masks, LANDLOCK_KEY_SOCKET);
+ if (landlock_unmask_layers(rule, handled_access, &layer_masks,
+ ARRAY_SIZE(layer_masks)))
+ return 0;
+ return -EACCES;
+}
+
+static int hook_socket_create(struct socket *const sock,
+ int family, int type, int protocol, int kern)
+{
+ return current_check_access_socket(sock, LANDLOCK_ACCESS_SOCKET_CREATE);
+}
+
+static struct security_hook_list landlock_hooks[] __ro_after_init = {
+ LSM_HOOK_INIT(socket_post_create, hook_socket_create),
+};
+
+__init void landlock_add_socket_hooks(void)
+{
+ security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks),
+ &landlock_lsmid);
+}
diff --git a/security/landlock/socket.h b/security/landlock/socket.h
index 2b8f9ae7d..152f4d427 100644
--- a/security/landlock/socket.h
+++ b/security/landlock/socket.h
@@ -10,6 +10,8 @@
#include "ruleset.h"
+__init void landlock_add_socket_hooks(void);
+
int landlock_append_socket_rule(struct landlock_ruleset *const ruleset,
const int domain, const int type,
access_mask_t access_rights);
--
2.34.1
More information about the Linux-security-module-archive
mailing list