Skip to content

Commit b8f82cb

Browse files
committed
Merge tag 'landlock-7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux
Pull Landlock update from Mickaël Salaün: "This adds a new Landlock access right for pathname UNIX domain sockets thanks to a new LSM hook, and a few fixes" * tag 'landlock-7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux: (23 commits) landlock: Document fallocate(2) as another truncation corner case landlock: Document FS access right for pathname UNIX sockets selftests/landlock: Simplify ruleset creation and enforcement in fs_test selftests/landlock: Check that coredump sockets stay unrestricted selftests/landlock: Audit test for LANDLOCK_ACCESS_FS_RESOLVE_UNIX selftests/landlock: Test LANDLOCK_ACCESS_FS_RESOLVE_UNIX selftests/landlock: Replace access_fs_16 with ACCESS_ALL in fs_test samples/landlock: Add support for named UNIX domain socket restrictions landlock: Clarify BUILD_BUG_ON check in scoping logic landlock: Control pathname UNIX domain socket resolution by path landlock: Use mem_is_zero() in is_layer_masks_allowed() lsm: Add LSM hook security_unix_find landlock: Fix kernel-doc warning for pointer-to-array parameters landlock: Fix formatting in tsync.c landlock: Improve kernel-doc "Return:" section consistency landlock: Add missing kernel-doc "Return:" sections selftests/landlock: Fix format warning for __u64 in net_test selftests/landlock: Skip stale records in audit_match_record() selftests/landlock: Drain stale audit records on init selftests/landlock: Fix socket file descriptor leaks in audit helpers ...
2 parents b206a6f + 3457a5c commit b8f82cb

29 files changed

Lines changed: 1650 additions & 794 deletions

File tree

Documentation/security/landlock.rst

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Landlock LSM: kernel documentation
77
==================================
88

99
:Author: Mickaël Salaün
10-
:Date: September 2025
10+
:Date: March 2026
1111

1212
Landlock's goal is to create scoped access-control (i.e. sandboxing). To
1313
harden a whole system, this feature should be available to any process,
@@ -89,6 +89,46 @@ this is required to keep access controls consistent over the whole system, and
8989
this avoids unattended bypasses through file descriptor passing (i.e. confused
9090
deputy attack).
9191

92+
.. _scoped-flags-interaction:
93+
94+
Interaction between scoped flags and other access rights
95+
--------------------------------------------------------
96+
97+
The ``scoped`` flags in &struct landlock_ruleset_attr restrict the
98+
use of *outgoing* IPC from the created Landlock domain, while they
99+
permit reaching out to IPC endpoints *within* the created Landlock
100+
domain.
101+
102+
In the future, scoped flags *may* interact with other access rights,
103+
e.g. so that abstract UNIX sockets can be allow-listed by name, or so
104+
that signals can be allow-listed by signal number or target process.
105+
106+
When introducing ``LANDLOCK_ACCESS_FS_RESOLVE_UNIX``, we defined it to
107+
implicitly have the same scoping semantics as a
108+
``LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET`` flag would have: connecting to
109+
UNIX sockets within the same domain (where
110+
``LANDLOCK_ACCESS_FS_RESOLVE_UNIX`` is used) is unconditionally
111+
allowed.
112+
113+
The reasoning is:
114+
115+
* Like other IPC mechanisms, connecting to named UNIX sockets in the
116+
same domain should be expected and harmless. (If needed, users can
117+
further refine their Landlock policies with nested domains or by
118+
restricting ``LANDLOCK_ACCESS_FS_MAKE_SOCK``.)
119+
* We reserve the option to still introduce
120+
``LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET`` in the future. (This would
121+
be useful if we wanted to have a Landlock rule to permit IPC access
122+
to other Landlock domains.)
123+
* But we can postpone the point in time when users have to deal with
124+
two interacting flags visible in the userspace API. (In particular,
125+
it is possible that it won't be needed in practice, in which case we
126+
can avoid the second flag altogether.)
127+
* If we *do* introduce ``LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET`` in the
128+
future, setting this scoped flag in a ruleset does *not reduce* the
129+
restrictions, because access within the same scope is already
130+
allowed based on ``LANDLOCK_ACCESS_FS_RESOLVE_UNIX``.
131+
92132
Tests
93133
=====
94134

Documentation/userspace-api/landlock.rst

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,8 @@ to be explicit about the denied-by-default access rights.
7777
LANDLOCK_ACCESS_FS_MAKE_SYM |
7878
LANDLOCK_ACCESS_FS_REFER |
7979
LANDLOCK_ACCESS_FS_TRUNCATE |
80-
LANDLOCK_ACCESS_FS_IOCTL_DEV,
80+
LANDLOCK_ACCESS_FS_IOCTL_DEV |
81+
LANDLOCK_ACCESS_FS_RESOLVE_UNIX,
8182
.handled_access_net =
8283
LANDLOCK_ACCESS_NET_BIND_TCP |
8384
LANDLOCK_ACCESS_NET_CONNECT_TCP,
@@ -127,6 +128,10 @@ version, and only use the available subset of access rights:
127128
/* Removes LANDLOCK_SCOPE_* for ABI < 6 */
128129
ruleset_attr.scoped &= ~(LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
129130
LANDLOCK_SCOPE_SIGNAL);
131+
__attribute__((fallthrough));
132+
case 6 ... 8:
133+
/* Removes LANDLOCK_ACCESS_FS_RESOLVE_UNIX for ABI < 9 */
134+
ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_RESOLVE_UNIX;
130135
}
131136
132137
This enables the creation of an inclusive ruleset that will contain our rules.
@@ -378,8 +383,8 @@ Truncating files
378383

379384
The operations covered by ``LANDLOCK_ACCESS_FS_WRITE_FILE`` and
380385
``LANDLOCK_ACCESS_FS_TRUNCATE`` both change the contents of a file and sometimes
381-
overlap in non-intuitive ways. It is recommended to always specify both of
382-
these together.
386+
overlap in non-intuitive ways. It is strongly recommended to always specify
387+
both of these together (either granting both, or granting none).
383388

384389
A particularly surprising example is :manpage:`creat(2)`. The name suggests
385390
that this system call requires the rights to create and write files. However,
@@ -391,6 +396,10 @@ It should also be noted that truncating files does not require the
391396
system call, this can also be done through :manpage:`open(2)` with the flags
392397
``O_RDONLY | O_TRUNC``.
393398

399+
At the same time, on some filesystems, :manpage:`fallocate(2)` offers a way to
400+
shorten file contents with ``FALLOC_FL_COLLAPSE_RANGE`` when the file is opened
401+
for writing, sidestepping the ``LANDLOCK_ACCESS_FS_TRUNCATE`` right.
402+
394403
The truncate right is associated with the opened file (see below).
395404

396405
Rights associated with file descriptors
@@ -700,6 +709,13 @@ enforce Landlock rulesets across all threads of the calling process
700709
using the ``LANDLOCK_RESTRICT_SELF_TSYNC`` flag passed to
701710
sys_landlock_restrict_self().
702711

712+
Pathname UNIX sockets (ABI < 9)
713+
-------------------------------
714+
715+
Starting with the Landlock ABI version 9, it is possible to restrict
716+
connections to pathname UNIX domain sockets (:manpage:`unix(7)`) using
717+
the new ``LANDLOCK_ACCESS_FS_RESOLVE_UNIX`` right.
718+
703719
.. _kernel_support:
704720

705721
Kernel support

include/linux/lsm_hook_defs.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,11 @@ LSM_HOOK(int, 0, post_notification, const struct cred *w_cred,
322322
LSM_HOOK(int, 0, watch_key, struct key *key)
323323
#endif /* CONFIG_SECURITY && CONFIG_KEY_NOTIFICATIONS */
324324

325+
#if defined(CONFIG_SECURITY_NETWORK) && defined(CONFIG_SECURITY_PATH)
326+
LSM_HOOK(int, 0, unix_find, const struct path *path, struct sock *other,
327+
int flags)
328+
#endif /* CONFIG_SECURITY_NETWORK && CONFIG_SECURITY_PATH */
329+
325330
#ifdef CONFIG_SECURITY_NETWORK
326331
LSM_HOOK(int, 0, unix_stream_connect, struct sock *sock, struct sock *other,
327332
struct sock *newsk)

include/linux/security.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1954,6 +1954,17 @@ static inline int security_mptcp_add_subflow(struct sock *sk, struct sock *ssk)
19541954
}
19551955
#endif /* CONFIG_SECURITY_NETWORK */
19561956

1957+
#if defined(CONFIG_SECURITY_NETWORK) && defined(CONFIG_SECURITY_PATH)
1958+
1959+
int security_unix_find(const struct path *path, struct sock *other, int flags);
1960+
1961+
#else /* CONFIG_SECURITY_NETWORK && CONFIG_SECURITY_PATH */
1962+
static inline int security_unix_find(const struct path *path, struct sock *other, int flags)
1963+
{
1964+
return 0;
1965+
}
1966+
#endif /* CONFIG_SECURITY_NETWORK && CONFIG_SECURITY_PATH */
1967+
19571968
#ifdef CONFIG_SECURITY_INFINIBAND
19581969
int security_ib_pkey_access(void *sec, u64 subnet_prefix, u16 pkey);
19591970
int security_ib_endport_manage_subnet(void *sec, const char *name, u8 port_num);

include/uapi/linux/landlock.h

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,9 @@ struct landlock_ruleset_attr {
116116
* ``LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF``, this flag only affects
117117
* future nested domains, not the one being created. It can also be used
118118
* with a @ruleset_fd value of -1 to mute subdomain logs without creating a
119-
* domain.
119+
* domain. When combined with %LANDLOCK_RESTRICT_SELF_TSYNC and a
120+
* @ruleset_fd value of -1, this configuration is propagated to all threads
121+
* of the current process.
120122
*
121123
* The following flag supports policy enforcement in multithreaded processes:
122124
*
@@ -248,6 +250,26 @@ struct landlock_net_port_attr {
248250
*
249251
* This access right is available since the fifth version of the Landlock
250252
* ABI.
253+
* - %LANDLOCK_ACCESS_FS_RESOLVE_UNIX: Look up pathname UNIX domain sockets
254+
* (:manpage:`unix(7)`). On UNIX domain sockets, this restricts both calls to
255+
* :manpage:`connect(2)` as well as calls to :manpage:`sendmsg(2)` with an
256+
* explicit recipient address.
257+
*
258+
* This access right only applies to connections to UNIX server sockets which
259+
* were created outside of the newly created Landlock domain (e.g. from within
260+
* a parent domain or from an unrestricted process). Newly created UNIX
261+
* servers within the same Landlock domain continue to be accessible. In this
262+
* regard, %LANDLOCK_ACCESS_FS_RESOLVE_UNIX has the same semantics as the
263+
* ``LANDLOCK_SCOPE_*`` flags.
264+
*
265+
* If a resolve attempt is denied, the operation returns an ``EACCES`` error,
266+
* in line with other filesystem access rights (but different to denials for
267+
* abstract UNIX domain sockets).
268+
*
269+
* This access right is available since the ninth version of the Landlock ABI.
270+
*
271+
* The rationale for this design is described in
272+
* :ref:`Documentation/security/landlock.rst <scoped-flags-interaction>`.
251273
*
252274
* Whether an opened file can be truncated with :manpage:`ftruncate(2)` or used
253275
* with `ioctl(2)` is determined during :manpage:`open(2)`, in the same way as
@@ -333,6 +355,7 @@ struct landlock_net_port_attr {
333355
#define LANDLOCK_ACCESS_FS_REFER (1ULL << 13)
334356
#define LANDLOCK_ACCESS_FS_TRUNCATE (1ULL << 14)
335357
#define LANDLOCK_ACCESS_FS_IOCTL_DEV (1ULL << 15)
358+
#define LANDLOCK_ACCESS_FS_RESOLVE_UNIX (1ULL << 16)
336359
/* clang-format on */
337360

338361
/**

net/unix/af_unix.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,11 +1231,15 @@ static struct sock *unix_find_bsd(struct sockaddr_un *sunaddr, int addr_len,
12311231
goto path_put;
12321232

12331233
err = -EPROTOTYPE;
1234-
if (sk->sk_type == type)
1235-
touch_atime(&path);
1236-
else
1234+
if (sk->sk_type != type)
12371235
goto sock_put;
12381236

1237+
err = security_unix_find(&path, sk, flags);
1238+
if (err)
1239+
goto sock_put;
1240+
1241+
touch_atime(&path);
1242+
12391243
path_put(&path);
12401244

12411245
return sk;

samples/landlock/sandboxer.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ static int parse_path(char *env_path, const char ***const path_list)
111111
LANDLOCK_ACCESS_FS_WRITE_FILE | \
112112
LANDLOCK_ACCESS_FS_READ_FILE | \
113113
LANDLOCK_ACCESS_FS_TRUNCATE | \
114-
LANDLOCK_ACCESS_FS_IOCTL_DEV)
114+
LANDLOCK_ACCESS_FS_IOCTL_DEV | \
115+
LANDLOCK_ACCESS_FS_RESOLVE_UNIX)
115116

116117
/* clang-format on */
117118

@@ -295,11 +296,12 @@ static bool check_ruleset_scope(const char *const env_var,
295296
LANDLOCK_ACCESS_FS_MAKE_SYM | \
296297
LANDLOCK_ACCESS_FS_REFER | \
297298
LANDLOCK_ACCESS_FS_TRUNCATE | \
298-
LANDLOCK_ACCESS_FS_IOCTL_DEV)
299+
LANDLOCK_ACCESS_FS_IOCTL_DEV | \
300+
LANDLOCK_ACCESS_FS_RESOLVE_UNIX)
299301

300302
/* clang-format on */
301303

302-
#define LANDLOCK_ABI_LAST 8
304+
#define LANDLOCK_ABI_LAST 9
303305

304306
#define XSTR(s) #s
305307
#define STR(s) XSTR(s)
@@ -438,6 +440,10 @@ int main(const int argc, char *const argv[], char *const *const envp)
438440
~LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON;
439441
__attribute__((fallthrough));
440442
case 7:
443+
case 8:
444+
/* Removes LANDLOCK_ACCESS_FS_RESOLVE_UNIX for ABI < 9 */
445+
ruleset_attr.handled_access_fs &=
446+
~LANDLOCK_ACCESS_FS_RESOLVE_UNIX;
441447
/* Must be printed for any ABI < LANDLOCK_ABI_LAST. */
442448
fprintf(stderr,
443449
"Hint: You should update the running kernel "

security/landlock/access.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
LANDLOCK_ACCESS_FS_IOCTL_DEV)
3535
/* clang-format on */
3636

37-
typedef u16 access_mask_t;
37+
typedef u32 access_mask_t;
3838

3939
/* Makes sure all filesystem access rights can be stored. */
4040
static_assert(BITS_PER_TYPE(access_mask_t) >= LANDLOCK_NUM_ACCESS_FS);
@@ -50,7 +50,7 @@ struct access_masks {
5050
access_mask_t fs : LANDLOCK_NUM_ACCESS_FS;
5151
access_mask_t net : LANDLOCK_NUM_ACCESS_NET;
5252
access_mask_t scope : LANDLOCK_NUM_SCOPE;
53-
};
53+
} __packed __aligned(sizeof(u32));
5454

5555
union access_masks_all {
5656
struct access_masks masks;

security/landlock/audit.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ static const char *const fs_access_strings[] = {
3737
[BIT_INDEX(LANDLOCK_ACCESS_FS_REFER)] = "fs.refer",
3838
[BIT_INDEX(LANDLOCK_ACCESS_FS_TRUNCATE)] = "fs.truncate",
3939
[BIT_INDEX(LANDLOCK_ACCESS_FS_IOCTL_DEV)] = "fs.ioctl_dev",
40+
[BIT_INDEX(LANDLOCK_ACCESS_FS_RESOLVE_UNIX)] = "fs.resolve_unix",
4041
};
4142

4243
static_assert(ARRAY_SIZE(fs_access_strings) == LANDLOCK_NUM_ACCESS_FS);

security/landlock/cred.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,8 @@ static void hook_cred_transfer(struct cred *const new,
2222
const struct landlock_cred_security *const old_llcred =
2323
landlock_cred(old);
2424

25-
if (old_llcred->domain) {
26-
landlock_get_ruleset(old_llcred->domain);
27-
*landlock_cred(new) = *old_llcred;
28-
}
25+
landlock_get_ruleset(old_llcred->domain);
26+
*landlock_cred(new) = *old_llcred;
2927
}
3028

3129
static int hook_cred_prepare(struct cred *const new,

0 commit comments

Comments
 (0)