1.\"- 2.\" SPDX-License-Identifier: BSD-2-Clause 3.\" 4.\" Copyright (c) 2024 Baptiste Daroussin <bapt@FreeBSD.org> 5.\" Copyright (c) 2024 The FreeBSD Foundation 6.\" 7.\" Portions of this documentation were written by Olivier Certner 8.\" <olce@FreeBSD.org> at Kumacom SARL under sponsorship from the FreeBSD 9.\" Foundation. 10.\" 11.Dd June 11, 2025 12.Dt MAC_DO 4 13.Os 14.Sh NAME 15.Nm mac_do 16.Nd "policy allowing unprivileged users to change process credentials" 17.Sh SYNOPSIS 18To compile the 19.Sy mac_do 20policy into your kernel, place the following lines in your kernel configuration 21file: 22.Bd -ragged -offset indent 23.Cd "options MAC" 24.Cd "options MAC_DO" 25.Ed 26.Pp 27Alternately, to load this policy module at boot time, place the following line 28in your kernel configuration file: 29.Bd -ragged -offset indent 30.Cd "options MAC" 31.Ed 32.Pp 33and in 34.Xr loader.conf 5 : 35.Bd -literal -offset indent 36mac_do_load="YES" 37.Ed 38.Sh DESCRIPTION 39The 40.Nm 41policy module allows unprivileged users to change process credentials according 42to rules configured by the administrator. 43It supports per-jail configuration. 44.Pp 45Currently, the 46.Nm 47policy module only produces effects to processes spawned from the 48.Pa /usr/bin/mdo 49executable, please see 50.Xr mdo 1 51for more details on this program. 52.Sh CREDENTIALS RULES 53Rules specify which transitions of process credentials 54.Nm 55will allow, based on current process credentials and the desired final ones. 56They are passed by an administrator in the form of a string having the specific 57syntax described below in a top-bottom manner. 58They have been designed to be able to finely describe the desired target 59credentials in a safe and compact way. 60.Ss Top-Level List of Rules 61At the top, rules are a possibly empty list of individual rules separated by 62a semi-colon 63.Pq Ql ";" : 64.Dl Ao rules Ac \ ⟶\ Oo Ao rule Ac Oo So ";" Sc Ao rule Ac Oc Ns * Oc 65They form a disjunction, i.e., 66.Nm 67authorizes a credentials transition as soon as at least one rule in the list 68matches. 69.Pp 70One rule is composed of a 71.Li Aq from 72part 73.Pq also called Dq match 74and a 75.Li Aq to 76part 77.Pq also called Dq target , 78in this order, separated by a greater-than sign 79.Pq Ql > : 80.Dl Ao rule Ac \ ⟶\ Ao from Ac So > Sc Ao to Ac 81.Ss Rule's Ao from Ac Part 82The first part of a rule, 83.Li Aq from , 84is matched against the credentials of the process requesting some credentials 85transition. 86It has the form: 87.Dl Ao from Ac \ ⟶\ Ao type Ac So = Sc Ao id Ac 88.Pp 89.Li Aq type 90must be: 91.Dl Ao type Ac \ ⟶\ Op So uid Sc | So gid Sc 92i.e., one of the literal strings 93.Ql uid 94or 95.Ql gid . 96.Li Aq id 97must be the numerical ID of a user or group and is matched against the current 98process real ID of the corresponding type, and on type 99.Ql gid 100additionally against the supplementary groups. 101.Ss Rule's Ao to Ac Part 102The second part of a rule, 103.Li Aq to , 104is a comma-separated 105.Pq Ql "," 106non-empty list of target clauses: 107.Dl Ao to Ac \ ⟶\ Ao target_clause Ac Oo So "," Sc Ao target_clause Ac Oc Ns * 108Target clauses of a given rule also form a disjunction, i.e., the IDs they 109specify are alternatives for the target credentials, except in some cases 110described below. 111.Pp 112The next subsections describe the syntax of target clauses, the defaults that 113apply and the principle of non-redundancy and non-contradiction in each rule's 114.Li Aq to 115part. 116.Ss Target Clauses 117A target clause in a rule's 118.Li Aq to 119part must be of one of the following forms: 120.Dl Ao target_clause Ac \ ⟶\ So any Sc 121.Dl Ao target_clause Ac \ ⟶\ Ao flags Ac Ao type Ac So = Sc Ao id Ac 122The first form is a compact way to specify that any target credentials are 123allowed. 124The second form is similar to that of 125.Li Aq from 126clauses, with the following extensions: 127.Bl -bullet -compact 128.It 129.Li Aq id 130may also be a literal 131.Ql * 132or 133.Ql any 134or 135.Ql "." . 136.Ql * 137and 138.Ql any 139both designate any ID for the specified 140.Li Aq type , 141and are treated identically. 142.Ql "." 143designates the process' current IDs for the specified 144.Li Aq type , 145as explained below. 146.It 147.Li Aq flags 148may contain at most one of the 149.Ql + , 150.Ql - 151and 152.Ql "!" 153characters, and may be non-empty only when 154.Li Aq type 155is 156.Ql gid . 157Additionally, if 158.Li Aq id 159is 160.Ql * 161or 162.Ql any , 163only the 164.Ql + 165flag may appear. 166.El 167.Pp 168For target clauses of 169.Ql gid 170type, an absence of flag indicates that the specified group ID is allowed as the 171real, effective and/or saved group IDs 172.Pq the Do primary Dc groups . 173Conversely, the presence of any allowed flag indicates that the specification 174concerns supplementary groups. 175Each flag has a specific meaning: 176.Bl -bullet -compact 177.It 178.Ql + 179indicates that the group ID is allowed as a supplementary group. 180.It 181.Ql "!" 182indicates that the group ID is mandatory, i.e., it must be listed in the 183supplementary groups. 184.It 185.Ql - 186indicates that the group ID must not be listed in the supplementary groups. 187.El 188A specification with 189.Ql - 190is only useful in conjunction with a 191.Ql + Ns 192-tagged specification where only one of them has 193.Ql "." 194as its 195.Li Aq id . 196Target clauses having the 197.Ql "!" 198or 199.Ql - 200flag are 201.Dq forcing 202clauses, and as such do not take part in the disjunction of the other 203target clauses but rather unconditionally apply in their rule. 204.Pp 205.Ql "." 206is a placeholder for IDs that the calling process already has on privilege 207check. 208For type 209.Ql uid , 210it designates any of the process' real, effective or 211saved user IDs. 212For type 213.Ql gid , 214its effect depends on whether flags are present. 215If none is present, it designates any of the process' real, effective or saved 216group IDs. 217If one is present, it designates any of the process' supplementary groups. 218.Ss Defaults for the Ao to Ac Part 219If the 220.Li Aq to 221part does not list a target clause with type 222.Ql uid , 223any of the current user IDs of the calling process is accepted. 224In other words, in this case, 225.Nm 226behaves as if a target clause of: 227.Dl uid=. 228had been listed. 229.Pp 230Similarly, if the 231.Li Aq to 232part does not list a target clause with type 233.Ql gid , 234all the groups of the calling process are assumed to be required. 235More precisely, each of the desired real, effective and saved group IDs must be 236one of the current real, effective or saved group ID, and all supplementary 237groups must be the same as those that are current. 238It is as if the 239.Li Aq to 240part had contained the following two clauses: 241.Dl gid=.,!gid=. 242.Ss Non-Redundancy and Non-Contradiction in a Ao to Ac Part 243No two target clauses of a single rule may express the exact same logical intent 244nor contradictory ones. 245.Pp 246In practice, no two clauses may display the same ID except for group IDs but 247only if, each time the same ID appears, it does so with a different flag, or no 248flags only once. 249Additionally, the specified flags in multiple occurences must not be 250contradictory. 251For example, the same group ID appearing with both 252.Ql + 253and 254.Ql - 255will cause rejection of the rule. 256.Ss Parsing Specifics 257Any amount of whitespace is allowed around tokens of the above grammar, except 258that there may be no spaces between 259.Li Aq flags 260and 261.Li Aq id 262in target clauses. 263.Pp 264For convenience, numerical IDs may be specified as negative integers, which are 265then converted to unsigned ones as specified in the C standard for the 266.Vt uid_t 267and 268.Vt gid_t 269types, which are both 64-bit unsigned integers. 270.Sh RUNTIME CONFIGURATION 271The following 272.Xr sysctl 8 273knobs are available: 274.Bl -tag -width indent 275.It Va security.mac.do.enabled 276Enable the 277.Nm 278policy. 279(Default: 1). 280.It Va security.mac.do.rules 281The list of credential rules, whose syntax is described in the 282.Sx CREDENTIALS RULES 283section above. 284This list is specific to each jail. 285Please see the 286.Sx JAIL SUPPORT 287section below for more details on the interaction of 288.Nm 289with jails. 290.It Va security.mac.do.print_parse_error 291Logs a message on trying to set incorrect rules via the 292.Va security.mac.do.rules 293.Xr sysctl 8 294knob. 295.El 296.Sh JAIL SUPPORT 297.Nm 298supports per-jail configuration of rules. 299.Pp 300By default, at creation, a new jail has no credentials rules, effectively 301disabling 302.Nm 303for its processes. 304.Pp 305The following jail parameters are defined: 306.Bl -tag -width indent 307.It Va mac.do 308Possible values are: 309.Bl -tag -width "'disable'" -compact 310.It Ql enable 311.Nm 312will enforce specific credential rules in the jail. 313The 314.Va mac.do.rules 315jail parameter must also be set in this case. 316.It Ql disable 317Disables 318.Nm 319in the jail. 320Strictly equivalent to jail creation's default behavior and to setting the rules 321to an empty string. 322.It Ql inherit 323The jail's credentials rules are inherited from the jail's parent 324.Pq which may themselves have been inherited . 325Modified rules propagate to all children jails configured for inheritance. 326.El 327.It Va mac.do.rules 328The credentials rules for the jail. 329It is always equal to the value that can be retrieved by the 330.Xr sysctl 8 331knob 332.Va security.mac.do.rules 333described in section 334.Sx RUNTIME CONFIGURATION . 335If set, and the jail parameter 336.Va mac.do 337is not so explicitly, the value of the latter will default to 338.Ql disable 339if empty, else to 340.Ql enable . 341.El 342.Pp 343Each jail must have 344.Xr mdo 1 345installed at path 346.Pa /usr/bin/mdo , 347as this path is currently not configurable. 348.Sh EXAMPLES 349Here are several examples of single rules matching processes having a real user 350ID of 10001: 351.Bl -tag -width indent 352.It Li uid=10001>uid=10002 353Allows the process to switch all of its real, effective or saved user ID to 35410002, but keeping the groups it is already in, and with the same 355primary/supplementary groups split. 356.It Li uid=10001>uid=10002,uid=10003 357Same as the first example, but also allows to switch to UID 10003 instead of 35810002, or possibly having both in different user IDs. 359.It Li uid=10001>uid=10002,gid=10002 360Same as the first example, but the new primary groups must be set to 10002 and 361no supplementary groups should be set. 362.It Li uid=10001>uid=10002,gid=10002,+gid=.\& 363Same as the previous example, but in addition allowing to retain any current 364supplementary groups. 365.It Li uid=10001>uid=10002,gid=10002,!gid=.\& 366Same as the previous example, but with the additional constraint that all 367current supplementary groups must be kept. 368.It Li uid=10001>uid=10002,gid=10002,+gid=.,-gid=10001 369Same as 370.Ql uid=10001>uid=10002,gid=10002,+gid=.\& 371above, but 10001 cannot be retained as a supplementary group. 372.It Li uid=10001>uid=10002,gid=10002,+gid=.,!gid=10003 373Same as 374.Ql uid=10001>uid=10002,gid=10002,+gid=.\& 375above, with the additional constraint that 10003 must appear in the 376supplementary groups. 377.It Li uid=10001>uid=10002,gid=*,+gid=* 378Same as the first example, but lifting any constraints on groups, allowing the 379process to become part of any groups it sees fit. 380.El 381.Pp 382Here are several examples of single rules matching processes having 10001 as 383their real group IDs or in their supplementary groups: 384.Bl -tag -width indent 385.It Li gid=10001>uid=0 386Makes 10001 a more powerful 387.Ql wheel 388group, allowing its members to switch to root without password. 389.It Li gid=10001>gid=10002 390Allows the process to enter GID 10002 as a primary group, but only if 391giving up all its supplementary groups. 392.It Li gid=10001>gid=10002,+gid=.\& 393Same as the previous example, but allows to retain any current supplementary 394groups. 395.It Li gid=10001>gid=10002,!gid=.\& 396Same as the previous example, but with the additional constraint that all 397current supplementary groups must be kept. 398.El 399.Sh SEE ALSO 400.Xr mdo 1 , 401.Xr setcred 2 , 402.Xr mac 4 , 403.Xr jail 8 , 404.Xr sysctl 8 405.Sh AUTHORS 406.An Olivier Certner Aq Mt olce@FreeBSD.org 407.An Baptiste Daroussin Aq Mt bapt@FreeBSD.org 408.Sh BUGS 409Currently, 410.Nm 411considers only credentials transitions requested through the 412.Xr setcred 2 413system call. 414This system call was in large part created so that 415.Nm 416can see whole credentials transitions to decide whether to authorize them, which 417the traditional UNIX's piecewise approach of successively changing different 418parts of them cannot allow. 419.Pp 420However, calls to traditional or standard credentials-changing functions can be 421considered as full transitions on their own, however limited, and as such should 422be equally monitored by 423.Nm . 424Future work will lift this restriction. 425.Sh SECURITY CONSIDERATIONS 426The threat model for 427.Nm 428is to consider userland programs as generally untrustable to decide upon which 429credentials changes are acceptable. 430It is in contrast with the traditional UNIX way to change credentials, in which 431specialized programs are installed with the setuid bit, giving them full 432administrator privileges so that they are effectively able to establish new 433ones. 434Vulnerabilities in such credentials-changing programs can have catastrophic 435consequences on the integrity of the system. 436.Pp 437Consequently, 438.Nm 439does not rely on companion userland programs to decide whether some credentials 440transition is acceptable. 441Instead, it maintains its own configuration independently from the userland 442password and group databases. 443Establishing this configuration currently itself relies on userland programs 444issuing calls to 445.Xr sysctl 3 446or 447.Xr jail 2 . 448It should thus be established near system boot or jail start, before any 449possible attacks could happen on the system, and further measures should be 450taken to ensure that potential corruptions does not affect the configuration in 451subsequent restarts, such as re-establishing pristine state or ensuring that the 452boot procedure up to the configuration of 453.Nm 454can be trusted. 455