From: Tahera Fahimi <fahimitahera@gmail.com>
To: "Mickaël Salaün" <mic@digikod.net>
Cc: "Günther Noack" <gnoack@google.com>,
"Paul Moore" <paul@paul-moore.com>,
"James Morris" <jmorris@namei.org>,
"Serge E. Hallyn" <serge@hallyn.com>,
linux-security-module@vger.kernel.org,
linux-kernel@vger.kernel.org,
"Björn Roy Baron" <bjorn3_gh@protonmail.com>,
"Jann Horn" <jannh@google.com>,
outreachy@lists.linux.dev, netdev@vger.kernel.org
Subject: Re: [PATCH v6] landlock: Add abstract unix socket connect restriction
Date: Wed, 10 Jul 2024 11:20:44 -0600 [thread overview]
Message-ID: <Zo7C7MUfnPApp0Np@tahera-OptiPlex-5000> (raw)
In-Reply-To: <20240704.uab4aveeYad0@digikod.net>
On Mon, Jul 08, 2024 at 05:35:48PM +0200, Mickaël Salaün wrote:
> Please add a user documentation with the next version. You can take
> some inspiration in commits that changed
> Documentation/userspace-api/landlock.rst
>
> You also need to extend samples/landlock/sandboxer.c with this new
> feature. You might want to use a new environment variable (LL_SCOPED)
> with "a" (for abstract unix socket) as the only valid content. New kind
> of sopping could add new characters. I'm not sure this is the most
> ergonomic, but let's go this way unless you have something else in mind.
Thanks for the feedback.
This will be added in the next patch.
> All the related patches (kernel change, tests, sample, documentation)
> should be in the same patch series, with a cover letter introducing the
> feature and pointing to the previous versions with links to
> https://lore.kernel.org/r/...
Noted.
>
> On Thu, Jun 27, 2024 at 05:30:17PM -0600, Tahera Fahimi wrote:
> > Abstract unix sockets are used for local inter-process communications
> > without a filesystem. Currently a sandboxed process can connect to a
>
> "local inter-process communications independant of the filesystem."
>
> > socket outside of the sandboxed environment, since Landlock has no
> > restriction for connecting to an abstract socket address. Access to
> > such sockets for a sandboxed process should be scoped the same way
> > ptrace is limited.
> >
> > Because of compatibility reasons and since landlock should be flexible,
>
> Landlock
[...]
> > diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h
> > index 68625e728f43..010aaca5b05a 100644
> > --- a/include/uapi/linux/landlock.h
> > +++ b/include/uapi/linux/landlock.h
> > @@ -37,6 +37,12 @@ struct landlock_ruleset_attr {
> > * rule explicitly allow them.
> > */
> > __u64 handled_access_net;
> > + /**
> > + * @scoped: Bitmask of scopes (cf. `Scope flags`_)
> > + * restricting a Landlock domain from accessing outside
> > + * resources(e.g. IPCs).
>
> A space is missing.
>
> > + */
> > + __u64 scoped;
> > };
> >
> > /*
> > @@ -266,4 +272,27 @@ struct landlock_net_port_attr {
> > #define LANDLOCK_ACCESS_NET_BIND_TCP (1ULL << 0)
> > #define LANDLOCK_ACCESS_NET_CONNECT_TCP (1ULL << 1)
> > /* clang-format on */
> > +
> > +/**
> > + * DOC: scope
> > + *
> > + * .scoped attribute handles a set of restrictions on kernel IPCs through
> > + * the following flags.
>
> I think you can remove this sentence.
>
[...]
> > diff --git a/security/landlock/task.c b/security/landlock/task.c
> > index 849f5123610b..acc6e0fbc111 100644
> > --- a/security/landlock/task.c
> > +++ b/security/landlock/task.c
> > @@ -13,6 +13,8 @@
> > #include <linux/lsm_hooks.h>
> > #include <linux/rcupdate.h>
> > #include <linux/sched.h>
> > +#include <net/sock.h>
> > +#include <net/af_unix.h>
> >
> > #include "common.h"
> > #include "cred.h"
> > @@ -108,9 +110,69 @@ static int hook_ptrace_traceme(struct task_struct *const parent)
> > return task_ptrace(parent, current);
> > }
> >
> > +static access_mask_t
> > +get_scoped_accesses(const struct landlock_ruleset *const domain)
> > +{
> > + access_mask_t access_dom = 0;
> > + size_t layer_level;
> > +
> > + for (layer_level = 0; layer_level < domain->num_layers; layer_level++)
> > + access_dom |= landlock_get_scope_mask(domain, layer_level);
> > + return access_dom;
> > +}
> > +
> > +static bool sock_is_scoped(struct sock *const other)
> > +{
> > + const struct landlock_ruleset *dom_other;
> > + const struct landlock_ruleset *const dom =
> > + landlock_get_current_domain();
> > +
> > + /* quick return if there is no domain or .scoped is not set */
> > + if (!dom || !get_scoped_accesses(dom))
> > + return true;
> > +
> > + /* the credentials will not change */
> > + lockdep_assert_held(&unix_sk(other)->lock);
> > + if (other->sk_type != SOCK_DGRAM) {
> > + dom_other = landlock_cred(other->sk_peer_cred)->domain;
>
> Why using different credentials for connected or not connected sockets?
> We should use the same consistent logic for both:
> other->sk_socket->file->f_cred (the process that created the socket, not
> the one listening).
The aim was to use the process's credential that utilized the socket for
connected sockets, and the process's credential created the socket for
non-connected sockets. However, I will change it and use the same
credential to keep it consistent for both cases.
> > + } else {
> > + dom_other =
> > + landlock_cred(other->sk_socket->file->f_cred)->domain;
> > + }
> > +
> > + if (!dom_other || !get_scoped_accesses(dom_other))
>
> What if only one layer in dom_other is scoped?
The function `get_scoped_accesses()` cover this.
> > + return false;
> > +
> > + /* other is scoped, they connect if they are in the same domain */
>
> This doesn't fit with each domain's scoping. It only considers no
> scopping for all domains, or all domains as scopped if any of them is.
> domain_scope_le() needs to be changed to follow each domain's contract.
Noted.
> > + return domain_scope_le(dom, dom_other);
> > +}
> > +
> > +static int hook_unix_stream_connect(struct sock *const sock,
> > + struct sock *const other,
> > + struct sock *const newsk)
> > +{
> > + if (sock_is_scoped(other))
> > + return 0;
> > +
> > + return -EPERM;
> > +}
> > +
> > +static int hook_unix_may_send(struct socket *const sock,
> > + struct socket *const other)
> > +{
> > + pr_warn("XXX %s:%d sock->file:%p other->file:%p\n", __func__, __LINE__,
> > + sock->file, other->file);
>
> Please remove debug code.
>
> > + if (sock_is_scoped(other->sk))
> > + return 0;
> > +
> > + return -EPERM;
> > +}
> > +
> > static struct security_hook_list landlock_hooks[] __ro_after_init = {
> > LSM_HOOK_INIT(ptrace_access_check, hook_ptrace_access_check),
> > LSM_HOOK_INIT(ptrace_traceme, hook_ptrace_traceme),
> > + LSM_HOOK_INIT(unix_stream_connect, hook_unix_stream_connect),
> > + LSM_HOOK_INIT(unix_may_send, hook_unix_may_send),
> > };
> >
> > __init void landlock_add_task_hooks(void)
> > --
> > 2.34.1
> >
> >
prev parent reply other threads:[~2024-07-10 17:20 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-06-27 23:30 [PATCH v6] landlock: Add abstract unix socket connect restriction Tahera Fahimi
2024-07-08 15:35 ` Mickaël Salaün
2024-07-10 17:20 ` Tahera Fahimi [this message]
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=Zo7C7MUfnPApp0Np@tahera-OptiPlex-5000 \
--to=fahimitahera@gmail.com \
--cc=bjorn3_gh@protonmail.com \
--cc=gnoack@google.com \
--cc=jannh@google.com \
--cc=jmorris@namei.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=mic@digikod.net \
--cc=netdev@vger.kernel.org \
--cc=outreachy@lists.linux.dev \
--cc=paul@paul-moore.com \
--cc=serge@hallyn.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;
as well as URLs for NNTP newsgroup(s).