From: Ondrej Mosnacek <omosnace@redhat.com>
To: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
Cc: stsp <stsp2@yandex.ru>, Willem de Bruijn <willemb@google.com>,
Jason Wang <jasowang@redhat.com>,
Jakub Kicinski <kuba@kernel.org>,
network dev <netdev@vger.kernel.org>,
Linux Security Module list
<linux-security-module@vger.kernel.org>,
SElinux list <selinux@vger.kernel.org>
Subject: Re: Possible mistake in commit 3ca459eaba1b ("tun: fix group permission check")
Date: Tue, 28 Jan 2025 15:20:45 +0100 [thread overview]
Message-ID: <CAFqZXNscJnX2VF-TyZaEC5nBtUUXdWPM2ejXTWBL8=5UyakssA@mail.gmail.com> (raw)
In-Reply-To: <67979d24d21bc_3f1a29434@willemb.c.googlers.com.notmuch>
On Mon, Jan 27, 2025 at 3:50 PM Willem de Bruijn
<willemdebruijn.kernel@gmail.com> wrote:
>
> stsp wrote:
> > 27.01.2025 12:10, Ondrej Mosnacek пишет:
> > > Hello,
> > >
> > > It looks like the commit in $SUBJ may have introduced an unintended
> > > change in behavior. According to the commit message, the intent was to
> > > require just one of {user, group} to match instead of both, which
> > > sounds reasonable, but the commit also changes the behavior for when
> > > neither of tun->owner and tun->group is set. Before the commit the
> > > access was always allowed, while after the commit CAP_NET_ADMIN is
> > > required in this case.
> > >
> > > I'm asking because the tun_tap subtest of selinux-testuite [1] started
> > > to fail after this commit (it assumed CAP_NET_ADMIN was not needed),
> > > so I'm trying to figure out if we need to change the test or if it
> > > needs to be fixed in the kernel.
> > >
> > > Thanks,
> > >
> > > [1] https://github.com/SELinuxProject/selinux-testsuite/
> > >
> > Hi, IMHO having the persistent
> > TAP device inaccessible by anyone
> > but the CAP_NET_ADMIN is rather
> > useless, so the compatibility should
> > be restored on the kernel side.
> > I'd raise the questions about adding
> > the CAP_NET_ADMIN checks into
> > TUNSETOWNER and/or TUNSETPERSIST,
> > but this particular change to TUNSETIFF,
> > at least on my side, was unintentional.
> >
> > Sorry about that. :(
>
> Thanks for the report Ondrej.
>
> Agreed that we need to reinstate this. I suggest this explicit
> extra branch after the more likely cases:
>
> @@ -585,6 +585,9 @@ static inline bool tun_capable(struct tun_struct *tun)
> return 1;
> if (gid_valid(tun->group) && in_egroup_p(tun->group))
> return 1;
> + if (!uid_valid(tun->owner) && !gid_valid(tun->group))
> + return 1;
> +
> return 0;
> }
That could work, but the semantics become a bit weird, actually: When
you set both uid and gid, one of them needs to match. If you unset
uid/gid, you get a stricter condition (gid/uid must match). And if you
then also unset the other one, you suddenly get a less strict
condition than the first two - nothing has to match. Might be
acceptable, but it may confuse people unless well documented.
Also there is another smaller issue in the new code that I forgot to
mention - with LSMs (such as SELinux) the ns_capable() call will
produce an audit record when the capability is denied by an LSM. These
audit records are meant to indicate that the permission was needed but
denied and that the policy was either breached or needs to be
adjusted. Therefore, the ns_capable() call should ideally only happen
after the user/group checks so that only accesses that actually
wouldn't succeed without the capability yield an audit record.
So I would suggest this version:
static inline bool tun_capable(struct tun_struct *tun)
{
const struct cred *cred = current_cred();
struct net *net = dev_net(tun->dev);
if (uid_valid(tun->owner) && uid_eq(cred->euid, tun->owner))
return 1;
if (gid_valid(tun->group) && in_egroup_p(tun->group))
return 1;
if (!uid_valid(tun->owner) && !gid_valid(tun->group))
return 1;
return ns_capable(net->user_ns, CAP_NET_ADMIN);
}
--
Ondrej Mosnacek
Senior Software Engineer, Linux Security - SELinux kernel
Red Hat, Inc.
next prev parent reply other threads:[~2025-01-28 14:21 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-01-27 9:10 Possible mistake in commit 3ca459eaba1b ("tun: fix group permission check") Ondrej Mosnacek
2025-01-27 10:00 ` stsp
2025-01-27 14:50 ` Willem de Bruijn
2025-01-27 14:58 ` stsp
2025-01-28 14:20 ` Ondrej Mosnacek [this message]
2025-01-28 14:45 ` stsp
2025-01-28 14:58 ` stsp
2025-01-28 15:04 ` Willem de Bruijn
2025-01-28 17:49 ` stsp
2025-01-28 22:59 ` Willem de Bruijn
2025-01-29 6:59 ` stsp
2025-01-29 14:12 ` Willem de Bruijn
2025-01-29 14:27 ` stsp
2025-01-30 16:46 ` Willem de Bruijn
2025-02-04 0:29 ` Paul Moore
2025-02-04 16:18 ` Ondrej Mosnacek
2025-02-04 19:40 ` Paul Moore
2025-02-06 3:04 ` Willem de Bruijn
2025-01-29 14:19 ` Willem de Bruijn
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='CAFqZXNscJnX2VF-TyZaEC5nBtUUXdWPM2ejXTWBL8=5UyakssA@mail.gmail.com' \
--to=omosnace@redhat.com \
--cc=jasowang@redhat.com \
--cc=kuba@kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=selinux@vger.kernel.org \
--cc=stsp2@yandex.ru \
--cc=willemb@google.com \
--cc=willemdebruijn.kernel@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;
as well as URLs for NNTP newsgroup(s).