[RFC PATCH v2 02/12] landlock: Add hook on socket creation
Mikhail Ivanov
ivanov.mikhail1 at huawei-partners.com
Fri May 24 09:30:05 UTC 2024
Add hook to security_socket_post_create(), which checks whether the socket
type and family are allowed by domain. Hook is called after initializing
the socket in the network stack to not wrongfully return EACCES for a
family-type pair, which is considered invalid by the protocol.
Signed-off-by: Mikhail Ivanov <ivanov.mikhail1 at huawei-partners.com>
---
Changes since v1:
* Use lsm hook arguments instead of struct socket fields as family-type
values.
* Packs socket family and type using helper.
* Fixes commit message.
* Formats with clang-format.
---
security/landlock/setup.c | 2 ++
security/landlock/socket.c | 70 ++++++++++++++++++++++++++++++++++++++
security/landlock/socket.h | 2 ++
3 files changed, 74 insertions(+)
diff --git a/security/landlock/setup.c b/security/landlock/setup.c
index 28519a45b11f..fd4e7e8f3cb2 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 1249a4a36503..b2775473b3dc 100644
--- a/security/landlock/socket.c
+++ b/security/landlock/socket.c
@@ -8,7 +8,9 @@
#include <linux/net.h>
#include <linux/socket.h>
#include <linux/stddef.h>
+#include <net/ipv6.h>
+#include "cred.h"
#include "limits.h"
#include "ruleset.h"
#include "socket.h"
@@ -58,3 +60,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, int family,
+ int type,
+ const access_mask_t access_request)
+{
+ 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;
+
+ id.key.data = pack_socket_key(family, type);
+
+ 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, family, type,
+ 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 8519357f1c39..5c36eae9732f 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 family, const int type,
access_mask_t access_rights);
--
2.34.1
More information about the Linux-security-module-archive
mailing list