lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251118134639.3314803-7-ivanov.mikhail1@huawei-partners.com>
Date: Tue, 18 Nov 2025 21:46:26 +0800
From: Mikhail Ivanov <ivanov.mikhail1@...wei-partners.com>
To: <mic@...ikod.net>, <gnoack@...gle.com>
CC: <willemdebruijn.kernel@...il.com>, <matthieu@...fet.re>,
	<linux-security-module@...r.kernel.org>, <netdev@...r.kernel.org>,
	<netfilter-devel@...r.kernel.org>, <yusongping@...wei.com>,
	<artem.kuzin@...wei.com>, <konstantin.meskhidze@...wei.com>
Subject: [RFC PATCH v4 06/19] landlock: Add hook on socket creation

Add hook on security_socket_create(), which checks whether the socket
of requested protocol is allowed by domain.

Due to support of masked protocols Landlock tries to find one of the
4 rules that can allow creation of requested protocol.

Signed-off-by: Mikhail Ivanov <ivanov.mikhail1@...wei-partners.com>
---
Changes since v3:
* Changes LSM hook from socket_post_create to socket_create so
  creation would be blocked before socket allocation and initialization.
* Uses credential instead of domain in hook_socket create.
* Removes get_raw_handled_socket_accesses.
* Adds checks for rules with wildcard type and protocol values.
* Minor refactoring, fixes.

Changes since v2:
* Adds check in `hook_socket_create()` to not restrict kernel space
  sockets.
* Inlines `current_check_access_socket()` in the `hook_socket_create()`.
* Fixes commit message.

Changes since v1:
* Uses 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 | 78 ++++++++++++++++++++++++++++++++++++++
 security/landlock/socket.h |  2 +
 3 files changed, 82 insertions(+)

diff --git a/security/landlock/setup.c b/security/landlock/setup.c
index bd53c7a56ab9..140a53b022f7 100644
--- a/security/landlock/setup.c
+++ b/security/landlock/setup.c
@@ -17,6 +17,7 @@
 #include "fs.h"
 #include "id.h"
 #include "net.h"
+#include "socket.h"
 #include "setup.h"
 #include "task.h"
 
@@ -68,6 +69,7 @@ static int __init landlock_init(void)
 	landlock_add_task_hooks();
 	landlock_add_fs_hooks();
 	landlock_add_net_hooks();
+	landlock_add_socket_hooks();
 	landlock_init_id();
 	landlock_initialized = true;
 	pr_info("Up and running.\n");
diff --git a/security/landlock/socket.c b/security/landlock/socket.c
index 28a80dcad629..d7e6e7b92b7a 100644
--- a/security/landlock/socket.c
+++ b/security/landlock/socket.c
@@ -103,3 +103,81 @@ int landlock_append_socket_rule(struct landlock_ruleset *const ruleset,
 
 	return err;
 }
+
+static int check_socket_access(const struct landlock_ruleset *dom,
+			       uintptr_t key,
+			       layer_mask_t (*const layer_masks)[],
+			       access_mask_t handled_access)
+{
+	const struct landlock_rule *rule;
+	struct landlock_id id = {
+		.type = LANDLOCK_KEY_SOCKET,
+	};
+
+	id.key.data = key;
+	rule = landlock_find_rule(dom, id);
+	if (landlock_unmask_layers(rule, handled_access, layer_masks,
+				   LANDLOCK_NUM_ACCESS_SOCKET))
+		return 0;
+	return -EACCES;
+}
+
+static int hook_socket_create(int family, int type, int protocol, int kern)
+{
+	layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_SOCKET] = {};
+	access_mask_t handled_access;
+	const struct access_masks masks = {
+		.socket = LANDLOCK_ACCESS_SOCKET_CREATE,
+	};
+	const struct landlock_cred_security *const subject =
+		landlock_get_applicable_subject(current_cred(), masks, NULL);
+	uintptr_t key;
+
+	if (!subject)
+		return 0;
+	/* Checks only user space sockets. */
+	if (kern)
+		return 0;
+
+	handled_access = landlock_init_layer_masks(
+		subject->domain, LANDLOCK_ACCESS_SOCKET_CREATE, &layer_masks,
+		LANDLOCK_KEY_SOCKET);
+	/*
+	 * Error could happen due to parameters are outside of the allowed range,
+	 * so this combination couldn't be added in ruleset previously.
+	 * Therefore, it's not permitted.
+	 */
+	if (pack_socket_key(family, type, protocol, &key) == -EACCES)
+		return -EACCES;
+	if (check_socket_access(subject->domain, key, &layer_masks,
+				handled_access) == 0)
+		return 0;
+
+	/* Ranges were already checked. */
+	(void)pack_socket_key(family, TYPE_ALL, protocol, &key);
+	if (check_socket_access(subject->domain, key, &layer_masks,
+				handled_access) == 0)
+		return 0;
+
+	(void)pack_socket_key(family, type, PROTOCOL_ALL, &key);
+	if (check_socket_access(subject->domain, key, &layer_masks,
+				handled_access) == 0)
+		return 0;
+
+	(void)pack_socket_key(family, TYPE_ALL, PROTOCOL_ALL, &key);
+	if (check_socket_access(subject->domain, key, &layer_masks,
+				handled_access) == 0)
+		return 0;
+
+	return -EACCES;
+}
+
+static struct security_hook_list landlock_hooks[] __ro_after_init = {
+	LSM_HOOK_INIT(socket_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 bd0ac74c39e2..3980a3d46534 100644
--- a/security/landlock/socket.h
+++ b/security/landlock/socket.h
@@ -15,4 +15,6 @@ int landlock_append_socket_rule(struct landlock_ruleset *const ruleset,
 				const s32 protocol,
 				access_mask_t access_rights);
 
+__init void landlock_add_socket_hooks(void);
+
 #endif /* _SECURITY_LANDLOCK_SOCKET_H */
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ