From owner-trustedbsd-discuss@freebsd.org Sat Nov 28 14:39:26 2020 Return-Path: Delivered-To: trustedbsd-discuss@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id CFAEB4A2552; Sat, 28 Nov 2020 14:39:26 +0000 (UTC) (envelope-from kevans@freebsd.org) Received: from smtp.freebsd.org (smtp.freebsd.org [96.47.72.83]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "smtp.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4CjvJt5Q0zz3t43; Sat, 28 Nov 2020 14:39:26 +0000 (UTC) (envelope-from kevans@freebsd.org) Received: from mail-qk1-f180.google.com (mail-qk1-f180.google.com [209.85.222.180]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "GTS CA 1O1" (verified OK)) (Authenticated sender: kevans) by smtp.freebsd.org (Postfix) with ESMTPSA id A79E08DC2; Sat, 28 Nov 2020 14:39:26 +0000 (UTC) (envelope-from kevans@freebsd.org) Received: by mail-qk1-f180.google.com with SMTP id i199so6872975qke.5; Sat, 28 Nov 2020 06:39:26 -0800 (PST) X-Gm-Message-State: AOAM533hOCQuzFjxxUQM9PpKSLXjxHrOQLviobxI0jJf2ei8h73xZh6p dlcXsy7VQ1rFNjKJ2y54B+nqqpibEBpcmSbhGaM= X-Google-Smtp-Source: ABdhPJzTBuG5KrgkFhRcsL7UoVItLgBHwf8OiaTkcsENJuIpNDInWtEojOKeRWvoERbhh7eJK3WkRXB5r4xhosOOSsI= X-Received: by 2002:ae9:e00e:: with SMTP id m14mr13764876qkk.34.1606574365869; Sat, 28 Nov 2020 06:39:25 -0800 (PST) MIME-Version: 1.0 References: <06F654BB-B087-4AE5-8599-E5837A85A850@FreeBSD.org> <6BA03DAD-BDCD-4A53-A80A-4B7B476B803C@FreeBSD.org> In-Reply-To: <6BA03DAD-BDCD-4A53-A80A-4B7B476B803C@FreeBSD.org> From: Kyle Evans Date: Sat, 28 Nov 2020 08:39:08 -0600 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: RFC: Jail privsets To: "Bjoern A. Zeeb" Cc: freebsd-jail , "freebsd-arch@freebsd.org" , trustedbsd-discuss@freebsd.org Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-BeenThere: trustedbsd-discuss@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: TrustedBSD General Discussion List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 28 Nov 2020 14:39:26 -0000 On Sat, Nov 28, 2020 at 7:19 AM Bjoern A. Zeeb wrote: > > On 27 Nov 2020, at 14:41, Kyle Evans wrote: > > > On Fri, Nov 27, 2020 at 6:15 AM Bjoern A. Zeeb 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