Re: netlink(4) fine grained access control
Kyle Evans <[email protected]> Tue, 7 Jul 2026 09:07:56 -0500
| Newsgroups | gmane.os.freebsd.architechture |
|---|---|
| Message-ID | <[email protected]> |
On 7/7/26 08:04, Kristof Provost wrote:
> On 6 Jul 2026, at 20:04, Kyle Evans wrote:
>
> I cast level 6 necromancy.
>
> /gurgle/
>
> On 9/15/25 10:45, Kristof Provost wrote:
>
> I’ve recently had a user raise an interesting issue (see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=289234 <https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=289234> )
>
> For background: pf is in the process of converting the userspace<>kernelspace interface to netlink. This is mostly a great improvement, but it does mean that only the root user (or, the user with PRIV_NETINET_PF privilege) can get information out of pf.
>
> That matches the default behaviour of the /dev/pf interface, but users can choose to allow other users or groups to access pf through a simple chmod/chown on /dev/pf. There’s no obvious way to do the same with netlink.
> From a brief inspection of the code I don’t think that any such mechanism exists. I don’t particularly want to invent anything specific to pf either.
>
> My initial impulse was to introduce a PRIV_NETINET_PF_RO priv, and to have users grant that to whatever account they’d normally allow access to /dev/pf, but the ability to set individual privileges for accounts seems to be a linux-ism (e.g. https://man7.org/linux/man-pages/man8/setcap.8.html <https://man7.org/linux/man-pages/man8/setcap.8.html> ) and not something we can do.
>
> So, any ideas or suggestions?
>
> genl on Linux doesn't seem to have a similar notion, beyond just not requiring privileges for some operations that just fetch statistics. Technically you could make the relevant operations unprivileged and EPERM them after checking appropriate ucred in the handler, but that's ugly.
>
> We're still in discussions about upstreaming a mac_bsdpriv that can grant arbitrary privileges,
>
> I’ve not actually looked all that deeply into what Linux does, but I’ve been assuming that they expect processes/users/containers to be granted additional privileges/capabilities.
> Hence my comments about setcap.
>
> In any event I don’t want to invent a pf-specific mechanism, but at the same time users do really seem to want to grant pf access to processes/jails that don’t get it by default.
> Up to and including letting old-style jails manage pf. I don’t understand, but apparently some people like their feet well ventilated.
>
Yeah, that's understandable.
> The current check is |if (cmd->cmd_priv != 0 && !nlp_has_priv(nlp, cmd->cmd_priv)) {| in https://cgit.freebsd.org/src/tree/sys/netlink/netlink_generic.c#n146 <https://cgit.freebsd.org/src/tree/sys/netlink/netlink_generic.c#n146>
> Hence my thinking that we want to be able to grant specific processes/users/jails additional privileges. That code also runs through the MAC hooks, so it seems plausible that mac_bsdpriv would be the answer here.
>
Right, I think mac_bsdpriv will be able to provide a solution that meets most needs here.
> but I think it would also be useful to add a MAC hook into |genl_handle_message| to pass the family + command context out to MAC for evaluation. That would open up some room for a policy that can do much finer-grained access control with just a little more MAC magic.
>
> Sure, I think I can see how that’d be useful. Would we integrate that in the existing cmd_priv check so that we can express ‘deny this if we don’t have this priv, but allow it if the MAC call says it’s okay’?
>
Yes, exactly- that opens up things like limiting root's ability to issue PFNL_CMD_STOP, for instance, or maybe you want a user that is just privileged enough to operate on addresses in a table (add/remove), but you don't want them to be able to meaningfully change rules otherwise. You could add a PRIV_NETINET_PF_TABLES and grant that differently, but what if you wanted to pretend that you aren't the maintainer or you wanted to limit it based on the table being targeted?
The latter's maybe a bad example because parsing the message is internal to pf_nl.c, but you could probably imagine that it's the kind of thing that could be of interest to someone- rather than forcing them to run pfctl(8) (or a limited-argument wrapper) with sudo (with argument limiting)/doas/mac_do, allowing them to accomplish just the limited scope they need without any point of escalation.
> Best regards,
> Kristof
>
Thanks,
Kyle Evans