Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 28 Nov 2020 08:39:08 -0600
From:      Kyle Evans <kevans@freebsd.org>
To:        "Bjoern A. Zeeb" <bz@freebsd.org>
Cc:        freebsd-jail <freebsd-jail@freebsd.org>,  "freebsd-arch@freebsd.org" <freebsd-arch@freebsd.org>, trustedbsd-discuss@freebsd.org
Subject:   Re: RFC: Jail privsets
Message-ID:  <CACNAnaGUEZqg_4WOgZ2zAOCboBGeeOY45ie_PSkVSK=3ct4b0g@mail.gmail.com>
In-Reply-To: <6BA03DAD-BDCD-4A53-A80A-4B7B476B803C@FreeBSD.org>
References:  <CACNAnaEKoBppjG8HH0KgYQv0EHPUcHmB3teyw1PQrjG3xsbXYQ@mail.gmail.com> <06F654BB-B087-4AE5-8599-E5837A85A850@FreeBSD.org> <CACNAnaGdn4o84UmKfA=m-fWvaUSHj-1zTVsBe9cdZZy0JMzEKg@mail.gmail.com> <6BA03DAD-BDCD-4A53-A80A-4B7B476B803C@FreeBSD.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Sat, Nov 28, 2020 at 7:19 AM Bjoern A. Zeeb <bz@freebsd.org> wrote:
>
> On 27 Nov 2020, at 14:41, Kyle Evans wrote:
>
> > On Fri, Nov 27, 2020 at 6:15 AM Bjoern A. Zeeb <bz@freebsd.org> wrote:
> >>
> >> On 27 Nov 2020, at 5:04, Kyle Evans wrote:
> >>
> >>> (Cross-posting to -arch and -jail for maximum reach)
> >>
> >> and trustedbsd now as that is where priv(9) came from [
> >> http://www.trustedbsd.org/privileges.html ]
> >>
> >>> A couple of times recently, I've had a need or desire to increase or
> >>> decrease privileges available to jails I create to some extent. You
> >>> can write a MAC policy for this, but at some point the downsides of
> >>> MAC policies for this became clear: it's either non-trivial to allow
> >>> the kind of flexibility you may need in configuring some of these
> >>> jails, and you have to rebuild the module otherwise.
> >>>
> >>> I've got a generally functional patch at [1] that is an approach I'd
> >>> like to request comments on for refining jail privileges. It creates
> >>> a
> >>> privset that can be assigned on a per-jail basis, and a creator with
> >>> PRIV_JAIL_SETPRIVS can specify any privset mask that's a subset of
> >>> the
> >>> parent prison.
> >>>
> >>> If no privset was specified at creation time, then we use the
> >>> default
> >>> logic that was previously in prison_priv_check().
> >>> prison_priv_check()
> >>> has been replaced with a much simpler check of the prison's privset
> >>> for the given privilege.
> >>>
> >>> As I was writing this, I identified the first problem with it: it
> >>> doesn't currently respond to ALLOW_* updates and grant the
> >>> appropriate
> >>> privileges after initialization time -- this is a pretty easy fix,
> >>> and
> >>> I will do so if anyone else finds this useful.
> >>>
> >>> The other caveat is that I have no idea if there's a useful way to
> >>> expose this to jail(8) users, but they're not really the primary
> >>> target for this -- the primary target is system application
> >>> developers
> >>> that want more fine control over what a jail they're creating can
> >>> do.
> >>>
> >>> This is an excellent foot-gun, but with great power comes great
> >>> responsibility.
> >>
> >> While I like the idea I am not sure I like the way it is done.
> >>
> >> I think it was a long-time goal of Robert (which just never happened
> >> to
> >> day) to make priv(9) configurable from user space.
> >>
> >> I am just not sure if hanging it off jails is the right answer.
> >> The jail-set is certainly the most extensive in the system, but the
> >> priv
> >> checks are everywhere and hanging them off, say a thread or
> >> credential,
> >> would allow people to do a lot more (also non-foot-shooting) than
> >> just
> >> modifying jails.
> >>
> >> That said, jails pretty much tie into the entire td/cred concept
> >> already
> >> so we could happily use them as a jumping platform for experimenting
> >> before extending it to the entire system if we are clear that this
> >> might
> >> not be the final stable way of doing things?
> >>
> >
> > Hi,
> >
> > So, FWIW, I had mapped this out a little further in my head but hadn't
> > quite decided on the best approach so I had stuck to jails for the
> > time being because that's the scenario that crops up the most for me
> > thus far.
> >
> > Here's the line of reasoning I went through up to this point, for full
> > disclosure:
> >
> > cred-based seems like a good approach, but the caveat is that they're
> > a little more difficult to target in a meaningful way to the admin,
> > AFAICT.
> >
> > I really like cpuset(1) and the accompanying interfaces, as there's a
> > lot of flexibility to be had there. It uses relatable concepts that
> > have obvious semantics:
> >
> > - You can restrict a jail, it cascades down
> > - You can restrict a process, it cascades down
> > - You can restrict a thread
> >
> > So I started there at the first level, because it doesn't actually
> > preclude the later levels. As you step down the tree, I think you
> > simply step away from the need to have prison_priv_check() at all and
> > just naturally push it all down into priv_check() because the fact
> > that they're in a jail has either already been accounted for or is now
> > completely irrelevant.
>
>
> To finish this for jails, like devfs rules or cpuset or FIB (though
> different interfaces),
> we=E2=80=99d have a one or two =E2=80=9Cdefault=E2=80=9D priv_sets define=
d in user space
> for jails then
> (if I understand you correctly), and jail(8)/jail_conf/jail syscalls
> would simply
> apply that (and it could be changed while running).
>

Yeah, so jail sets are a little tricky, and to be honest I haven't
really thought about how to cope with common jail sets. The
complication arises because you have various allow flags that
typically default to off and turn privileges on, but your common sets
would have to include them. So, you'd probably end up with:

privset 0: All privs available to the superuser (not considering
superuser policy just yet)
privset 1: All privs available to jails (assuming most permissive, all
allow flags on and assuming a new vnet on VIMAGE systems)

So jails would typically inherit privset 1, but they'd have to mask
out based on vnet/allow flags out of necessity. Now, that's not
terrible, but I think we'd have to do a couple more things to reduce
maintenance burden on folks introducing privs:

1.) Clearly define a central table that maps pr_flags <-> privs where
there's a 1:1 mapping (most common, though PRIV_VFS_*MOUNT* are a
little more complicated)
2.) Walk said table when we're defining privs in privset 1
3.) Walk said table when we're determining what to mask out

I suspect the vnet set is large enough that we'd just have a separate
kernel-internal mask for "vnet privs". In any event, for most people,
there will be one of three places that you might touch when adding a
new priv flag or pr_flag mapping to a priv, but it should still be
obvious what you want: either you want a conditionally added flag, you
want to influence the default jail policy, or you want to change the
vnet policy. The latter two scenarios might even be a little easier,
because you don't need to wade through these gigantic switch
statements with a lot of cases to determine where you really want it
to go.

> And yes, that would indeed simplify our jail and network stack (and some
> other)
> code quite a bit.
>
> I=E2=80=99d love this (step-by-step or in whole right away) :-)
>

:-)

I'm looking to see if I can define a useful abstraction from
cpuset/domainset that would limit the amount of duplication needed for
this, then I'll post a v2 to Phabricator.

Thanks,

Kyle Evans



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CACNAnaGUEZqg_4WOgZ2zAOCboBGeeOY45ie_PSkVSK=3ct4b0g>