[PATCH v5 2/9] landlock: Control pathname UNIX domain socket resolution by path

Mickaël Salaün mic at digikod.net
Sun Mar 8 09:09:21 UTC 2026


On Sun, Feb 15, 2026 at 11:51:50AM +0100, Günther Noack wrote:
> * Add a new access right LANDLOCK_ACCESS_FS_RESOLVE_UNIX, which
>   controls the look up operations for named UNIX domain sockets.  The
>   resolution happens during connect() and sendmsg() (depending on
>   socket type).
> * Hook into the path lookup in unix_find_bsd() in af_unix.c, using a
>   LSM hook.  Make policy decisions based on the new access rights
> * Increment the Landlock ABI version.
> * Minor test adaptions to keep the tests working.
> 
> With this access right, access is granted if either of the following
> conditions is met:
> 
> * The target socket's filesystem path was allow-listed using a
>   LANDLOCK_RULE_PATH_BENEATH rule, *or*:
> * The target socket was created in the same Landlock domain in which
>   LANDLOCK_ACCESS_FS_RESOLVE_UNIX was restricted.
> 
> In case of a denial, connect() and sendmsg() return EACCES, which is
> the same error as it is returned if the user does not have the write
> bit in the traditional Unix file system permissions of that file.

It is not the same error code as for scoped abstract unix socket
(EPERM), but it makes sense because the scope restrictions are closer to
ambient rights (i.e. similar to a network isolation), whereas here the
final denial comes from a missing FS rule (and all FS access checks may
return EACCES).  It would be worth mentioning this difference in the
user documentation.

> 
> This feature was created with substantial discussion and input from
> Justin Suess, Tingmao Wang and Mickaël Salaün.
> 
> Cc: Tingmao Wang <m at maowtm.org>
> Cc: Justin Suess <utilityemal77 at gmail.com>
> Cc: Mickaël Salaün <mic at digikod.net>
> Suggested-by: Jann Horn <jannh at google.com>
> Link: https://github.com/landlock-lsm/linux/issues/36
> Signed-off-by: Günther Noack <gnoack3000 at gmail.com>
> ---
>  include/uapi/linux/landlock.h                |  10 ++
>  security/landlock/access.h                   |  11 +-
>  security/landlock/audit.c                    |   1 +
>  security/landlock/fs.c                       | 102 ++++++++++++++++++-
>  security/landlock/limits.h                   |   2 +-
>  security/landlock/syscalls.c                 |   2 +-
>  tools/testing/selftests/landlock/base_test.c |   2 +-
>  tools/testing/selftests/landlock/fs_test.c   |   5 +-
>  8 files changed, 128 insertions(+), 7 deletions(-)

> +static int hook_unix_find(const struct path *const path, struct sock *other,
> +			  int flags)
> +{
> +	const struct landlock_ruleset *dom_other;
> +	const struct landlock_cred_security *subject;
> +	struct layer_access_masks layer_masks;
> +	struct landlock_request request = {};
> +	static const struct access_masks fs_resolve_unix = {
> +		.fs = LANDLOCK_ACCESS_FS_RESOLVE_UNIX,
> +	};
> +
> +	/* Lookup for the purpose of saving coredumps is OK. */
> +	if (unlikely(flags & SOCK_COREDUMP))
> +		return 0;
> +
> +	/* Access to the same (or a lower) domain is always allowed. */
> +	subject = landlock_get_applicable_subject(current_cred(),
> +						  fs_resolve_unix, NULL);
> +
> +	if (!subject)
> +		return 0;
> +
> +	if (!landlock_init_layer_masks(subject->domain, fs_resolve_unix.fs,
> +				       &layer_masks, LANDLOCK_KEY_INODE))
> +		return 0;
> +
> +	/* Checks the layers in which we are connecting within the same domain. */
> +	dom_other = landlock_cred(other->sk_socket->file->f_cred)->domain;
> +	unmask_scoped_access(subject->domain, dom_other, &layer_masks,
> +			     fs_resolve_unix.fs);
> +
> +	if (layer_access_masks_empty(&layer_masks))

I don't see the point of this helper and this call wrt the following
is_access_to_paths_allowed() call and the is_layer_masks_allowed()
check.

> +		return 0;
> +
> +	/* Checks the connections to allow-listed paths. */
> +	if (is_access_to_paths_allowed(subject->domain, path,
> +				       fs_resolve_unix.fs, &layer_masks,
> +				       &request, NULL, 0, NULL, NULL, NULL))
> +		return 0;
> +
> +	landlock_log_denial(subject, &request);
> +	return -EACCES;
> +}



More information about the Linux-security-module-archive mailing list