FreeBSD’s kernel provides quite sophisticated privilege model that extends the traditional UNIX user-and-group one. Here I’ll show how to leverage it to grant access to specific privileges to group of non-root users.
mac(9) allows creating pluggable modules with policies that can extend existing base system security definitions.
struct mac_policy_ops consist of many entry points that we can use to amend the behaviour.
This time, I wanted to grant a privilege to change realtime priority to a selected group. While Linux kernel lets you specify a named group, FreeBSD doesn’t have such ability, hence I created this very simple policy.
The privilege check can be extended using two user supplied functions: priv_check and priv_grant. The first one can be used to further restrict existing privileges, i.e. you can disallow some specific priv to be used in jails, etc. The second one is used to explicitly grant extra privileges not available for the target in base configuration.
The core of the
mac_rtprio module is dead simple. I defined sysctl tree for two oids: enable (on/off switch for the policy) and gid (the GID target has to be member of), then I specified our custom version of
Body of my granting function is even simpler. If the policy is disabled or the privilege that is being checked is not
PRIV_SCHED_RTPRIO, we simply skip and return
EPERM. If the user is member of the designated group we return 0 that’ll allow the action – target would change realtime privileges.
Full source code of the module is available on GitHub.