[PATCH 1/6] landlock: Add LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET scope bit to uAPI
Tingmao Wang
m at maowtm.org
Sun Dec 28 12:45:40 UTC 2025
Add the new scope bit to the uAPI header, add documentation, and bump ABI
version to 8.
This documentation edit specifically calls out the security implications of
not restricting sockets.
Fix some minor cosmetic issue in landlock.h around the changed lines as
well.
Signed-off-by: Tingmao Wang <m at maowtm.org>
---
Documentation/userspace-api/landlock.rst | 37 ++++++++++++++++---
include/uapi/linux/landlock.h | 8 +++-
security/landlock/limits.h | 2 +-
security/landlock/syscalls.c | 2 +-
tools/testing/selftests/landlock/base_test.c | 2 +-
.../testing/selftests/landlock/scoped_test.c | 2 +-
6 files changed, 42 insertions(+), 11 deletions(-)
diff --git a/Documentation/userspace-api/landlock.rst b/Documentation/userspace-api/landlock.rst
index 903d2ad11852..8f4cad332b63 100644
--- a/Documentation/userspace-api/landlock.rst
+++ b/Documentation/userspace-api/landlock.rst
@@ -83,7 +83,8 @@ to be explicit about the denied-by-default access rights.
LANDLOCK_ACCESS_NET_CONNECT_TCP,
.scoped =
LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
- LANDLOCK_SCOPE_SIGNAL,
+ LANDLOCK_SCOPE_SIGNAL |
+ LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET,
};
Because we may not know which kernel version an application will be executed
@@ -133,6 +134,10 @@ version, and only use the available subset of access rights:
supported_restrict_flags &= ~(LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON |
LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF |
LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF);
+ __attribute__((fallthrough));
+ case 7:
+ /* Removes LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET for ABI < 8 */
+ ruleset_attr.scoped &= ~LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET;
}
This enables the creation of an inclusive ruleset that will contain our rules.
@@ -334,10 +339,15 @@ The operations which can be scoped are:
This limits the sending of signals to target processes which run within the
same or a nested Landlock domain.
-``LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET``
- This limits the set of abstract :manpage:`unix(7)` sockets to which we can
- :manpage:`connect(2)` to socket addresses which were created by a process in
- the same or a nested Landlock domain.
+``LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET`` and ``LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET``
+ This limits the set of :manpage:`unix(7)` sockets to which we can
+ :manpage:`connect(2)` to socket addresses which were created by a
+ process in the same or a nested Landlock domain.
+ ``LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET`` applies to abstract sockets,
+ and ``LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET`` applies to pathname
+ sockets. Even though pathname sockets are represented in the
+ filesystem, Landlock filesystem rules do not currently control access
+ to them.
A :manpage:`sendto(2)` on a non-connected datagram socket is treated as if
it were doing an implicit :manpage:`connect(2)` and will be blocked if the
@@ -610,6 +620,23 @@ Landlock audit events with the ``LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF``,
sys_landlock_restrict_self(). See Documentation/admin-guide/LSM/landlock.rst
for more details on audit.
+Pathname UNIX socket (ABI < 8)
+------------------------------
+
+Starting with the Landlock ABI version 8, it is possible to restrict
+connections to a pathname (non-abstract) :manpage:`unix(7)` socket by
+setting ``LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET`` to the ``scoped`` ruleset
+attribute. This works the same way as the abstract socket scoping.
+
+This allows sandboxing applications using only Landlock to protect against
+bypasses relying on connecting to Unix sockets of other services running
+under the same user. These services typically assumes that any process
+capable of connecting to a local Unix socket, or connecting with the
+expected user credentials, is trusted. Without this protection, sandbox
+escapes may be possible, especially when running in a standard desktop
+environment, such as by using systemd-run, or sockets exposed by other
+common applications.
+
.. _kernel_support:
Kernel support
diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h
index f030adc462ee..590c6d4171a0 100644
--- a/include/uapi/linux/landlock.h
+++ b/include/uapi/linux/landlock.h
@@ -364,10 +364,14 @@ struct landlock_net_port_attr {
* related Landlock domain (e.g., a parent domain or a non-sandboxed process).
* - %LANDLOCK_SCOPE_SIGNAL: Restrict a sandboxed process from sending a signal
* to another process outside the domain.
+ * - %LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET: Restrict a sandboxed process from
+ * connecting to a pathname UNIX socket created by a process outside the
+ * related Landlock domain.
*/
/* clang-format off */
#define LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET (1ULL << 0)
-#define LANDLOCK_SCOPE_SIGNAL (1ULL << 1)
-/* clang-format on*/
+#define LANDLOCK_SCOPE_SIGNAL (1ULL << 1)
+#define LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET (1ULL << 2)
+/* clang-format on */
#endif /* _UAPI_LINUX_LANDLOCK_H */
diff --git a/security/landlock/limits.h b/security/landlock/limits.h
index 65b5ff051674..d653e14dba10 100644
--- a/security/landlock/limits.h
+++ b/security/landlock/limits.h
@@ -27,7 +27,7 @@
#define LANDLOCK_MASK_ACCESS_NET ((LANDLOCK_LAST_ACCESS_NET << 1) - 1)
#define LANDLOCK_NUM_ACCESS_NET __const_hweight64(LANDLOCK_MASK_ACCESS_NET)
-#define LANDLOCK_LAST_SCOPE LANDLOCK_SCOPE_SIGNAL
+#define LANDLOCK_LAST_SCOPE LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET
#define LANDLOCK_MASK_SCOPE ((LANDLOCK_LAST_SCOPE << 1) - 1)
#define LANDLOCK_NUM_SCOPE __const_hweight64(LANDLOCK_MASK_SCOPE)
diff --git a/security/landlock/syscalls.c b/security/landlock/syscalls.c
index 0116e9f93ffe..66fd196be85a 100644
--- a/security/landlock/syscalls.c
+++ b/security/landlock/syscalls.c
@@ -161,7 +161,7 @@ static const struct file_operations ruleset_fops = {
* Documentation/userspace-api/landlock.rst should be updated to reflect the
* UAPI change.
*/
-const int landlock_abi_version = 7;
+const int landlock_abi_version = 8;
/**
* sys_landlock_create_ruleset - Create a new ruleset
diff --git a/tools/testing/selftests/landlock/base_test.c b/tools/testing/selftests/landlock/base_test.c
index 7b69002239d7..f4b1a275d8d9 100644
--- a/tools/testing/selftests/landlock/base_test.c
+++ b/tools/testing/selftests/landlock/base_test.c
@@ -76,7 +76,7 @@ TEST(abi_version)
const struct landlock_ruleset_attr ruleset_attr = {
.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE,
};
- ASSERT_EQ(7, landlock_create_ruleset(NULL, 0,
+ ASSERT_EQ(8, landlock_create_ruleset(NULL, 0,
LANDLOCK_CREATE_RULESET_VERSION));
ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0,
diff --git a/tools/testing/selftests/landlock/scoped_test.c b/tools/testing/selftests/landlock/scoped_test.c
index b90f76ed0d9c..7f83512a328d 100644
--- a/tools/testing/selftests/landlock/scoped_test.c
+++ b/tools/testing/selftests/landlock/scoped_test.c
@@ -12,7 +12,7 @@
#include "common.h"
-#define ACCESS_LAST LANDLOCK_SCOPE_SIGNAL
+#define ACCESS_LAST LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET
TEST(ruleset_with_unknown_scope)
{
--
2.52.0
More information about the Linux-security-module-archive
mailing list