public inbox for linux-security-module@vger.kernel.org
 help / color / mirror / Atom feed
From: "Mickaël Salaün" <mic@digikod.net>
To: Tingmao Wang <m@maowtm.org>
Cc: "Günther Noack" <gnoack@google.com>,
	"Demi Marie Obenour" <demiobenour@gmail.com>,
	"Alyssa Ross" <hi@alyssa.is>, "Jann Horn" <jannh@google.com>,
	"Tahera Fahimi" <fahimitahera@gmail.com>,
	"Justin Suess" <utilityemal77@gmail.com>,
	linux-security-module@vger.kernel.org
Subject: Re: [PATCH v2 2/6] landlock: Implement LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET
Date: Thu, 29 Jan 2026 22:27:33 +0100	[thread overview]
Message-ID: <20260129.iCah3fash9ch@digikod.net> (raw)
In-Reply-To: <a6d6479888d9d216a3f2e7bb133523f856f92461.1767115163.git.m@maowtm.org>

On Tue, Dec 30, 2025 at 05:20:20PM +0000, Tingmao Wang wrote:
> Extend the existing abstract UNIX socket scoping to pathname sockets as
> well.  Basically all of the logic is reused between the two types, just
> that pathname sockets scoping are controlled by another bit, and has its
> own audit request type (since the current one is named
> "abstract_unix_socket").
> 
> Closes: https://github.com/landlock-lsm/linux/issues/51
> Signed-off-by: Tingmao Wang <m@maowtm.org>
> ---
> 
> Changes in v2:
> - Factor out common code in hook_unix_stream_connect and
>   hook_unix_may_send into check_socket_access(), and inline
>   is_abstract_socket().
> 
>  security/landlock/audit.c |   4 ++
>  security/landlock/audit.h |   1 +
>  security/landlock/task.c  | 109 ++++++++++++++++++++++----------------
>  3 files changed, 67 insertions(+), 47 deletions(-)
> 
> diff --git a/security/landlock/audit.c b/security/landlock/audit.c
> index e899995f1fd5..0626cc553ab0 100644
> --- a/security/landlock/audit.c
> +++ b/security/landlock/audit.c
> @@ -75,6 +75,10 @@ get_blocker(const enum landlock_request_type type,
>  		WARN_ON_ONCE(access_bit != -1);
>  		return "scope.abstract_unix_socket";
>  
> +	case LANDLOCK_REQUEST_SCOPE_PATHNAME_UNIX_SOCKET:
> +		WARN_ON_ONCE(access_bit != -1);
> +		return "scope.pathname_unix_socket";
> +
>  	case LANDLOCK_REQUEST_SCOPE_SIGNAL:
>  		WARN_ON_ONCE(access_bit != -1);
>  		return "scope.signal";
> diff --git a/security/landlock/audit.h b/security/landlock/audit.h
> index 92428b7fc4d8..1c9ce8588102 100644
> --- a/security/landlock/audit.h
> +++ b/security/landlock/audit.h
> @@ -21,6 +21,7 @@ enum landlock_request_type {
>  	LANDLOCK_REQUEST_NET_ACCESS,
>  	LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET,
>  	LANDLOCK_REQUEST_SCOPE_SIGNAL,
> +	LANDLOCK_REQUEST_SCOPE_PATHNAME_UNIX_SOCKET,
>  };
>  
>  /*
> diff --git a/security/landlock/task.c b/security/landlock/task.c
> index 833bc0cfe5c9..10dc356baf6f 100644
> --- a/security/landlock/task.c
> +++ b/security/landlock/task.c
> @@ -232,35 +232,81 @@ static bool domain_is_scoped(const struct landlock_ruleset *const client,
>  	return false;
>  }
>  
> +/**
> + * sock_is_scoped - Check if socket connect or send should be restricted
> + *    based on scope controls.
> + *
> + * @other: The server socket.
> + * @domain: The client domain.
> + * @scope: The relevant scope bit to check (i.e. pathname or abstract).
> + *
> + * Returns: True if connect should be restricted, false otherwise.
> + */
>  static bool sock_is_scoped(struct sock *const other,
> -			   const struct landlock_ruleset *const domain)
> +			   const struct landlock_ruleset *const domain,
> +			   access_mask_t scope)
>  {
>  	const struct landlock_ruleset *dom_other;
>  
>  	/* The credentials will not change. */
>  	lockdep_assert_held(&unix_sk(other)->lock);
>  	dom_other = landlock_cred(other->sk_socket->file->f_cred)->domain;
> -	return domain_is_scoped(domain, dom_other,
> -				LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
> +	return domain_is_scoped(domain, dom_other, scope);
>  }
>  
> -static bool is_abstract_socket(struct sock *const sock)
> +/* Allow us to quickly test if the current domain scopes any form of socket */

Missing final dot.

> +static const struct access_masks unix_scope = {
> +	.scope = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
> +		 LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET,
> +};
> +
> +/*
> + * UNIX sockets can have three types of addresses: pathname (a filesystem path),
> + * unnamed (not bound to an address), and abstract (sun_path[0] is '\0').
> + * Unnamed sockets include those created with socketpair() and unbound sockets.
> + * We do not restrict unnamed sockets since they have no address to identify.

Not because they have no address but because they cannot be used to
reach a new peer, right?

> + */
> +static int
> +check_socket_access(struct sock *const other,
> +		    const struct landlock_cred_security *const subject,
> +		    const size_t handle_layer)
>  {
> -	struct unix_address *addr = unix_sk(sock)->addr;
> +	const struct unix_address *addr = unix_sk(other)->addr;
> +	access_mask_t scope;
> +	enum landlock_request_type request_type;
>  
> +	/* Unnamed sockets are not restricted. */
>  	if (!addr)
> -		return false;
> +		return 0;
>  
> +	/*
> +	 * Abstract and pathname Unix sockets have separate scope and audit

UNIX

> +	 * request type.
> +	 */
>  	if (addr->len >= offsetof(struct sockaddr_un, sun_path) + 1 &&
> -	    addr->name->sun_path[0] == '\0')
> -		return true;
> +	    addr->name->sun_path[0] == '\0') {
> +		scope = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET;
> +		request_type = LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET;
> +	} else {
> +		scope = LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET;
> +		request_type = LANDLOCK_REQUEST_SCOPE_PATHNAME_UNIX_SOCKET;
> +	}
>  
> -	return false;
> -}
> +	if (!sock_is_scoped(other, subject->domain, scope))
> +		return 0;
>  
> -static const struct access_masks unix_scope = {
> -	.scope = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET,
> -};
> +	landlock_log_denial(subject, &(struct landlock_request) {
> +		.type = request_type,
> +		.audit = {
> +			.type = LSM_AUDIT_DATA_NET,
> +			.u.net = &(struct lsm_network_audit) {
> +				.sk = other,
> +			},
> +		},
> +		.layer_plus_one = handle_layer + 1,
> +	});
> +	return -EPERM;
> +}
>  
>  static int hook_unix_stream_connect(struct sock *const sock,
>  				    struct sock *const other,
> @@ -275,23 +321,7 @@ static int hook_unix_stream_connect(struct sock *const sock,
>  	if (!subject)
>  		return 0;
>  
> -	if (!is_abstract_socket(other))
> -		return 0;
> -
> -	if (!sock_is_scoped(other, subject->domain))
> -		return 0;
> -
> -	landlock_log_denial(subject, &(struct landlock_request) {
> -		.type = LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET,
> -		.audit = {
> -			.type = LSM_AUDIT_DATA_NET,
> -			.u.net = &(struct lsm_network_audit) {
> -				.sk = other,
> -			},
> -		},
> -		.layer_plus_one = handle_layer + 1,
> -	});
> -	return -EPERM;
> +	return check_socket_access(other, subject, handle_layer);
>  }
>  
>  static int hook_unix_may_send(struct socket *const sock,
> @@ -302,6 +332,7 @@ static int hook_unix_may_send(struct socket *const sock,
>  		landlock_get_applicable_subject(current_cred(), unix_scope,
>  						&handle_layer);
>  
> +	/* Quick return for non-landlocked tasks. */
>  	if (!subject)
>  		return 0;
>  
> @@ -312,23 +343,7 @@ static int hook_unix_may_send(struct socket *const sock,
>  	if (unix_peer(sock->sk) == other->sk)
>  		return 0;
>  
> -	if (!is_abstract_socket(other->sk))
> -		return 0;
> -
> -	if (!sock_is_scoped(other->sk, subject->domain))
> -		return 0;
> -
> -	landlock_log_denial(subject, &(struct landlock_request) {
> -		.type = LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET,
> -		.audit = {
> -			.type = LSM_AUDIT_DATA_NET,
> -			.u.net = &(struct lsm_network_audit) {
> -				.sk = other->sk,
> -			},
> -		},
> -		.layer_plus_one = handle_layer + 1,
> -	});
> -	return -EPERM;
> +	return check_socket_access(other->sk, subject, handle_layer);
>  }
>  
>  static const struct access_masks signal_scope = {
> -- 
> 2.52.0
> 

  reply	other threads:[~2026-01-29 21:46 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-12-30 17:20 [PATCH v2 0/6] Landlock: Implement scope control for pathname Unix sockets Tingmao Wang
2025-12-30 17:20 ` [PATCH v2 1/6] landlock: Add LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET scope bit to uAPI Tingmao Wang
2026-01-29 21:27   ` Mickaël Salaün
2025-12-30 17:20 ` [PATCH v2 2/6] landlock: Implement LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET Tingmao Wang
2026-01-29 21:27   ` Mickaël Salaün [this message]
2025-12-30 17:20 ` [PATCH v2 3/6] samples/landlock: Support LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET Tingmao Wang
2026-01-29 21:27   ` Mickaël Salaün
2026-01-31 17:48     ` Tingmao Wang
2026-02-02 20:14       ` Mickaël Salaün
2025-12-30 17:20 ` [PATCH v2 4/6] selftests/landlock: Support pathname socket path in set_unix_address Tingmao Wang
2025-12-30 17:20 ` [PATCH v2 5/6] selftests/landlock: Repurpose scoped_abstract_unix_test.c for pathname sockets too Tingmao Wang
2026-01-29 21:28   ` Mickaël Salaün
2026-02-02  0:06     ` Tingmao Wang
2025-12-30 17:20 ` [PATCH v2 6/6] selftests/landlock: Add pathname socket variants for more tests Tingmao Wang
2026-01-29 21:28   ` Mickaël Salaün
2025-12-30 23:16 ` [PATCH v2 0/6] Landlock: Implement scope control for pathname Unix sockets Günther Noack
2025-12-31 16:54   ` Demi Marie Obenour
2026-01-09 12:01     ` Mickaël Salaün
2026-01-31 17:41       ` Tingmao Wang
2026-02-02 20:32         ` Mickaël Salaün
2026-02-02 22:03           ` Justin Suess
2026-02-03  1:26             ` Tingmao Wang
2026-02-03 17:54               ` Günther Noack
2026-02-03 21:53                 ` Tingmao Wang
2026-02-04 11:44                   ` Günther Noack
2026-02-04 16:36                     ` Justin Suess
2026-02-04 18:28                       ` Mickaël Salaün
2026-02-05 15:22                         ` Justin Suess
     [not found]                         ` <44d216aa-9680-4cf5-bbf0-173869111212@gmail.com>
2026-02-05 19:15                           ` Mickaël Salaün
2026-02-08  2:57                             ` Tingmao Wang
2026-02-08 13:44                               ` Günther Noack
2026-02-08 13:49                               ` Günther Noack
2026-02-04 17:43                     ` Mickaël Salaün
2026-02-05  8:02                       ` Günther Noack
2026-02-05 10:27                         ` Mickaël Salaün
2026-02-08  2:57                           ` Tingmao Wang
2026-02-08 20:37                             ` Günther Noack
2026-02-08 20:48                               ` Tingmao Wang
2026-02-08 23:21                                 ` Günther Noack
2026-02-09 20:20                                 ` Mickaël Salaün
2026-02-04 17:39               ` Mickaël Salaün

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260129.iCah3fash9ch@digikod.net \
    --to=mic@digikod.net \
    --cc=demiobenour@gmail.com \
    --cc=fahimitahera@gmail.com \
    --cc=gnoack@google.com \
    --cc=hi@alyssa.is \
    --cc=jannh@google.com \
    --cc=linux-security-module@vger.kernel.org \
    --cc=m@maowtm.org \
    --cc=utilityemal77@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox