30.4 Mandatory Access Control Framework (MAC Framework)
Overview
FreeBSD's Mandatory Access Control (MAC) framework allows fine-grained control over system security through loadable security policy modules. MAC can load access control modules to enforce security policies. Some modules provide protection for narrow subsets of the system, hardening specific services, while others provide comprehensive labeled security across all subjects and objects. The term "mandatory" means that control is exercised by the administrator and the operating system, in contrast to the default Discretionary Access Control (DAC), where users make their own access decisions.
MAC policies cannot override traditional Unix security mechanisms (file permissions and superuser checks); they only impose additional restrictions on top of DAC. In other words, even if MAC is configured to allow access, if DAC denies it, the operation will still fail. MAC policies can restrict root privileges, which is one of the key distinctions from DAC.
The MAC framework was first introduced in FreeBSD 5.0 as part of the TrustedBSD project, designed by Robert Watson and implemented by the Network Associates Laboratories (NAI Labs) security research division, under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), part of the DARPA CHATS research program.
The MAC framework design references IEEE POSIX.1e Draft 17 (formerly known as POSIX.1e), which aimed to define security extensions for operating systems, including access control lists (ACLs), auditing, and mandatory access control. POSIX.1e was never finalized as an official standard, and FreeBSD's MAC implementation is the result of independent evolution by the TrustedBSD project based on practical requirements, not fully equivalent to any approved international or industry standard.
Improper MAC configuration may result in inability to access the system, disruption of normal user operations, or inability to start Xorg. Furthermore, MAC alone should not be relied upon to protect the system. The MAC framework only enhances existing security policies; without sound security practices and regular security audits, the system remains vulnerable.
The examples in this chapter are for demonstration purposes only and should not be implemented on production systems. Any security policy implementation requires thorough understanding, proper design, and comprehensive testing.
While this section covers a wide range of MAC framework security issues, it does not address the development of new MAC security policy modules. Many of the policy modules in the MAC framework have specific characteristics and can also be used for testing purposes.
Standards Compliance
FreeBSD's MAC implementation is related to the following standards and drafts:
IEEE POSIX.1e Draft 17: The mac(3) userspace API and the maclabel(7) label format are based on this draft. The API has only weak similarity to the POSIX draft because the POSIX API cannot express certain concepts required for flexible and extensible access control.
File System Access Control Lists: The ACL mechanism defined in the POSIX.1e draft is independently implemented by FreeBSD through the getfacl(1)/setfacl(1) commands and is not part of the MAC framework.
Label Semantics: The semantics of the three labeling policies (Biba, MLS, LOMAC) respectively follow their own security model theories, which originate from classical military security policy and commercial integrity policy research.
Key Terminology
The following key terms are used when discussing the MAC framework:
Compartment: A group of programs and data that need to be partitioned or isolated; users must be explicitly authorized to access specific system components. Compartments represent groupings such as workgroups, departments, projects, or topics, enabling need-to-know security policies.
Integrity: The level of trust that can be assigned to data. Higher data integrity means greater trust in it.
Level: An increasing or decreasing setting of a security attribute. A higher level means greater security.
Label: A security attribute that can be applied to system objects such as files and directories, comparable to a confidentiality stamp. When a label is applied to a file, it describes its security attributes, allowing access only to files, users, and resources with similar security settings. The meaning and interpretation of label values depend on policy configuration: some policies treat labels as representations of object integrity or confidentiality, while others use labels to hold access rules.
Multilabel: This attribute is a file system option that can be set with tunefs(8) in single-user mode, via fstab(5) during the boot process, or when creating a new file system. This option allows administrators to apply different MAC labels to different objects, and is only applicable to security policy modules that support labeling.
Single label: A policy where the entire file system enforces access control using one label for data flow. When
multilabelis not set, all files follow the same label setting.Object: An entity through which information flows under the direction of a subject, including directories, files, fields, screens, keyboards, memory, magnetic storage, printers, and other data storage or transmission devices. An object is a data container or system resource; accessing an object means accessing its data.
Subject: An active entity that causes information to flow between objects, such as a user, user process, or system process. In FreeBSD, a subject is almost always a thread executing operations on behalf of a user within a process.
Policy: A set of rules defining how objectives are achieved, typically documenting how a certain class of objects is handled. In this chapter, a policy is viewed as a set of rules that control data and information flow and define access permissions.
High-watermark: A policy that allows raising the security level to access higher-level information, with most processes reverting to their original level upon completion. Currently, the FreeBSD MAC framework does not include such a policy.
Low-watermark: A policy that allows lowering the security level to access lower-security information, with most processes reverting to the user's original level upon completion. In FreeBSD, only mac_lomac(4) uses this policy.
Sensitivity: Most commonly used in Multilevel Security (MLS) discussions. A sensitivity level describes the importance or confidentiality of data; the higher the level, the more important the data's confidentiality or secrecy.
Understanding MAC Labels
MAC labels are security attributes that can be applied to subjects and objects in the system. When setting labels, administrators need to understand their implications to prevent unexpected or unintended system behavior. The available attributes for objects depend on the loaded policy modules, and each module interprets attributes differently.
The security label on an object is used by policies as part of access control decisions. In some policies, the label contains all the information for the decision; in others, the label may be processed as part of a larger rule set.
Label policies are divided into single-label and multilabel categories. The system uses single-label by default. Administrators should understand the advantages and disadvantages of each to implement a policy that matches the system's security model.
A single-label policy enforces one set of access permissions across the system, with lower management overhead but reduced flexibility for labeling policies, allowing only one label per subject or object. However, in many environments, a single label is sufficient.
A single-label policy is somewhat similar to DAC in that root configures the policy to place users in appropriate categories and access levels. The significant difference is that many policy modules can also restrict root. Basic control of objects is delegated to groups, but root can revoke or modify settings at any time.
When appropriate, multilabel can be passed to tunefs(8) to set a multilabel policy for UFS file systems. A multilabel policy allows each subject or object to have its own independent MAC label. The decision between single-label or multilabel is only necessary for policies that implement labeling functionality, such as biba, lomac, and mls. Some policies (such as seeotheruids, portacl, partition) do not use labels at all. The multilabel feature is natively supported on UFS2 file systems and must be enabled by running tunefs -l enable in single-user mode. MAC label support for ZFS file systems may differ due to implementation differences.
Because everything in a file system has a label — including directories, files, and even device nodes — using a multilabel policy on a partition and establishing a multilabel security model may increase management overhead.
The following command will set multilabel multilabel on the specified UFS file system. This command should be executed in single-user mode and is not required for swap file systems:
Note
If the above command is not executed in single-user mode, it will always display the error message "tunefs: / is not clean - run fsck."
Some users have encountered issues when setting the multilabel flag on the root partition (such as label configuration not taking effect, or the system failing to boot properly). For specific troubleshooting steps, see the "MAC Framework Troubleshooting" section at the end of this chapter.
Since multilabel policies are set per file system, a multilabel policy may not be needed if the file system layout is well-organized. Consider a FreeBSD web server MAC security model design: by default, everything on this computer's file system uses the single label biba/high. If the web server needs to run at biba/low to prevent upward writes, it can be installed on a separate UFS file system /usr/local set to biba/low.
Configuring Labels
Almost all configuration for label policy modules can be accomplished using base system tools. These commands configure objects or subjects, or provide a simple interface for configuration control and verification.
All configuration can be done using setfmac (set MAC labels for system objects) and setpmac (set labels for system subjects). For example, to set the MAC label biba of test to high:
Upon successful execution, the command returns to the prompt with no error message.
The common error Permission denied typically occurs when attempting to set or modify a label on a restricted object. Other situations may result in different failures: the file may not belong to the user attempting to relabel the object, the object may not exist, or the object may be read-only. The enforced policy may prohibit a process from relabeling a file for reasons related to the file's attributes, the process's attributes, or the new label value's attributes. For example, a low-integrity user attempting to change a high-integrity file's label, or a low-integrity user attempting to change a low-integrity file's label to high-integrity, will both fail.
System administrators can use setpmac to assign a different label to an invoked process, overriding the policy module settings:
For currently running processes (such as sshd), getpmac is typically used to obtain their label. This command takes a process ID (PID) instead of a command name. If a user attempts to access a file outside their permissions, an Operation not permitted error will be displayed due to the restrictions of the loaded policy module.
Predefined Labels
Some FreeBSD policy modules that support labeling provide three predefined labels: low, equal, and high:
low
The lowest label setting an object or subject can have. Setting this label prevents access to objects or subjects labeled as high.
equal
Disables or exempts the subject or object from the policy; should only be placed on objects that are exempt from the policy.
high
Grants the highest setting available to an object or subject in the Biba and MLS policy modules.
Such policy modules include mac_biba(4), mac_mls(4), and mac_lomac(4). Each predefined label establishes different information flow directives; refer to the module manual pages for general label configuration characteristics.
Numeric Labels
The Biba and MLS policy modules support numeric labels, which can be set to indicate precise levels of hierarchical control. This numeric value is used to divide information into different classification groups, allowing access only to that group or higher levels. For example:
This can be interpreted as "Biba policy label/grade 10: compartments 2, 3, and 6: (grade 5 …)."
In this example, the first grade is the effective grade with effective compartments, the second is the low grade, and the last is the high grade. Most configurations do not require this level of granularity, as it constitutes advanced configuration.
System objects have only a current grade and compartment. System subjects reflect the range of available permissions in the system and the network interfaces used for access control.
The grades and compartments in subject-object pairs are used to construct a dominance relationship: the subject dominates the object, the object dominates the subject, neither dominates the other, or they dominate each other. "Mutual dominance" occurs when two labels are equal. Due to Biba information flow characteristics, a user possesses a set of permissions that may correspond to project compartment permissions, and objects also possess a set of compartments. A user may need to use su or setpmac to reduce permissions to access objects in unrestricted compartments.
User Labels
Users need to configure labels in /etc/login.conf using login classes to ensure their files and processes interact correctly with the system security policy. Each policy module that uses labels implements user class settings.
To set default labels for the user class enforced by MAC, add a label entry. An example label entry containing each policy module is shown below. Note that in actual configuration, administrators would not enable all policy modules. It is recommended to read this entire section before implementation.
Users cannot modify the default values, but after logging in they can change labels within the policy constraints. The above example tells the Biba policy that a process has a minimum integrity of 5, a maximum of 15, and a default effective label of 10. The process runs at 10 until it chooses to change (possibly because the user uses setpmac), constrained by the Biba-configured range.
After modifying the /etc/login.conf file, the login class capability database must be rebuilt using cap_mkdb.
Many sites have numerous users and need to divide them into different user classes with in-depth planning, which can make management complex.
Network Interface Labels
Labels can be set on network interfaces to help control data flow across the network. Network interface labels function the same way as object labels in each policy. For example, in Biba, a user at a high setting is not allowed to access a network interface labeled low.
When setting MAC labels on network interfaces, the maclabel parameter can be used with ifconfig:
This example sets a MAC label of biba/equal on the bge0 interface. When using settings like biba/high(low-high), the entire label should be quoted to prevent errors.
Each policy module that supports labeling has tunable parameters that can be used to disable MAC labels on network interfaces. Setting the label to equal has a similar effect. For details on tunable parameters, see the sysctl output, policy manual pages, and subsequent sections of this chapter.
Planning Security Configuration
Before implementing any MAC policy, planning is recommended. The planning phase should consider implementation requirements and objectives, such as:
How to classify information and resources on the target system.
Which information or resources to restrict access to, and what access restrictions to impose.
Which MAC modules are needed to achieve these objectives.
Before implementing MAC on a production system, a trial run should be conducted on a trusted system with its configuration. Different environments have different requirements, and establishing a complete security configuration can reduce post-deployment modifications.
Consider how the MAC framework enhances overall system security. The various security policy modules provided by the MAC framework can be used to protect networks and file systems, or to prevent users from accessing specific ports and sockets. Perhaps the best use of policy modules is to load multiple modules simultaneously to provide an MLS environment, an approach distinct from policies that only target specific purposes and harden isolated system elements. The downside of MLS is increased management overhead.
However, this overhead is acceptable compared to the long-term benefits of the framework's flexible policy selection with low performance overhead. Reducing support for unnecessary policies can improve overall system performance while providing selection flexibility. A good implementation should consider overall security requirements and effectively deploy the various security policy modules provided by the framework.
MAC ensures that users cannot arbitrarily change system security attributes. All user utilities, programs, and scripts must operate within the access rules of the selected security policy modules, and MAC access rule control rests with the system administrator.
It is the system administrator's responsibility to carefully select the correct security policy modules. For environments requiring network access control restrictions, mac_portacl(4), mac_ifoff(4), and mac_biba(4) are good starting points. For environments requiring strict confidentiality of file system objects, mac_bsdextended(4) and mac_mls(4) may be considered.
Policy decisions can be based on network configuration. If only specific users should be allowed to access ssh(1), mac_portacl(4) is an appropriate choice. On the file system side, access to objects may be confidential for some users but not for others. For example, a large development team might be split into smaller project groups: developers in project A must not access objects written by developers in project B, but both groups may need to access objects created by developers in project C. Using the different security policy modules provided by the MAC framework, users can be divided into groups and granted appropriate access permissions.
Each security policy module has a unique approach to handling system security. Module selection should be based on a well-considered security policy, which may need revision and reimplementation. Understanding the different security policy modules provided by the MAC framework helps administrators choose the best solution.
Implementing MAC is similar to implementing a firewall; care must be taken to prevent the administrator from being completely locked out. The ability to revert to a previous configuration should be considered, and extra caution should be exercised when implementing MAC through remote connections.
Available MAC Policies
The default FreeBSD kernel includes options MAC. The source code path is sys/security.
After testing a module, add the module name to /boot/loader.conf for loading at boot time. Each module also provides a kernel option for administrators who choose to compile a custom kernel.
Module Loading Timing Restrictions
mac_biba(4)
Biba integrity policy
Yes
Boot only
mac_bsdextended(4)
File system firewall
No
Any time
mac_ddb(4)
Kernel debugger interface restriction
No
Any time
mac_do(4)
Non-privileged user credential changes
No
Any time
mac_ifoff(4)
Interface silencing
No
Any time
mac_ipacl(4)
IP address access control
No
Any time
mac_lomac(4)
Low-Watermark integrity policy
Yes
Boot only
mac_mls(4)
Multilevel security confidentiality policy
Yes
Boot only
mac_none(4)
Null policy module (no access control effect)
No
Any time
mac_ntpd(4)
NTP unprivileged operation
No
Any time
mac_partition(4)
Process partition policy
Yes
Any time
mac_portacl(4)
Port binding access control
No
Any time
mac_priority(4)
Scheduling priority policy
No
Any time
mac_seeotheruids(4)
Cross-user visibility policy
No
Any time
The following sections describe each of these policies individually. The last three labeling policies (Biba, MLS, LOMAC) support using integer values instead of the three default labels.
MAC See Other UIDs Policy
Module name: mac_seeotheruids.ko
Kernel configuration line: options MAC_SEEOTHERUIDS
Boot option: mac_seeotheruids_load="YES"
The mac_seeotheruids(4) module provides an independent sysctl tunable tree security.mac.seeotheruids.*, whose functionality is similar to security.bsd.see_other_uids and security.bsd.see_other_gids. This option does not require prior label setup and can transparently interoperate with other modules.
After loading the module, the following sysctl tunable parameters are available to control functionality:
security.mac.seeotheruids.enabledenables the module and enforces the default setting, denying users the ability to view processes and sockets owned by other users.security.mac.seeotheruids.suser_privilegedwhen set to a non-zero value, allows the superuser (root) to view processes and sockets of all users.security.mac.seeotheruids.specificgid_enabledallows specifying a group to be exempt from this policy. Set using thesecurity.mac.seeotheruids.specificgid=XXXtunable, replacing XXX with the numeric group ID.security.mac.seeotheruids.primarygroup_enabledis used to exempt specific primary groups. Users in the exempted group can view each other's processes and sockets.
MAC BSD Extended Policy
Module name: mac_bsdextended.ko
Kernel configuration line: options MAC_BSDEXTENDED
Boot option: mac_bsdextended_load="YES"
The mac_bsdextended(4) module implements a file system firewall, providing an extension to the standard file system permission model that allows administrators to create firewall-like rule sets to protect files, utilities, and directories within the file system hierarchy. When a file system object is accessed, the rule list is traversed until a matching rule is found or the end is reached. This behavior can be changed with security.mac.bsdextended.firstmatch_enabled. Similar to other FreeBSD firewall modules, a file containing access control rules can be created and read by the system at boot time using rc.conf(5) variables.
The rule list can be entered using ugidfw(8), with syntax similar to ipfw(8). Additional tools can be written using libugidfw(3) library functions.
After loading the mac_bsdextended(4) module, the current rule configuration can be viewed with the following command:
By default, no rules are defined and all content is fully accessible. Create a rule to block all users but not affect root:
Warning
This rule will prevent all non-root users from doing anything, potentially rendering the system completely unusable. This is shown only as a negative example and must never be used in production environments.
While simple, this rule is an extremely poor practice: it prevents all users from executing any command. A more practical example is blocking all access by user1 to user2's home directory (including directory listings):
not uid user2 can be used instead of user1 to enforce the same access restrictions for all users. However, root is not affected by this rule.
This module should be used with extra caution, as improper use may block access to portions of the file system.
MAC DDB Policy
Module name: mac_ddb.ko
Kernel configuration line: options MAC_DDB
Boot option: mac_ddb_load="YES"
The mac_ddb(4) policy module restricts the subset of commands available at the kernel debugger ddb(4) command prompt. Allowed commands are limited to those that do not involve arbitrary memory read or write operations, preventing the extraction of system secrets while retaining sufficient debugging functionality to diagnose kernel panics. For example, trace or show registers are allowed, but show buffer addr is not.
All debugger commands declared with the DB_CMD_MEMSAFE flag are permitted. The policy also provides a validation function that conditionally allows certain additional commands based on user parameters.
Once loaded, mac_ddb also ensures that only the ddb(4) debugger backend can be executed, not gdb(4).
This policy does not use labels.
MAC DO Policy
Module name: mac_do.ko
Kernel configuration line: options MAC_DO
Boot option: mac_do_load="YES"
The mac_do(4) policy module allows non-privileged users to change process credentials (user ID and group ID) according to administrator-configured rules, supporting per-jail independent configuration.
This policy takes effect through the /usr/bin/mdo executable; for details, refer to mdo(1). Rules are specified as strings in from>to format, where each rule contains a from part (matching current credentials) and a to part (target credentials), with multiple rules separated by semicolons ;.
The following sysctl tunable parameters are available:
security.mac.do.enabledenables or disables the mac_do policy (default: 1).security.mac.do.rulescredential rule list, configured independently per jail.
mac_do supports per-jail rule configuration. Each jail must have mdo(1) installed at the /usr/bin/mdo path. Jail parameters include mac.do (enable/disable/inherit) and mac.do.rules.
Unlike the traditional setuid approach, mac_do does not rely on setuid programs to determine whether a credential change is acceptable; instead, the kernel makes the decision based on administrator-configured rules, thereby avoiding the security risks of setuid program vulnerabilities.
MAC Interface Silencing Policy
Module name: mac_ifoff.ko
Kernel configuration line: options MAC_IFOFF
Boot option: mac_ifoff_load="YES"
The mac_ifoff(4) module is used to dynamically disable network interfaces, preventing them from coming up during system boot. It does not use labels and does not depend on any other MAC modules.
This module is primarily controlled through the following sysctl tunable parameters:
security.mac.ifoff.lo_enabledenables or disables all traffic on the loopback interface lo(4).security.mac.ifoff.bpfrecv_enabledenables or disables all traffic on the Berkeley Packet Filter interface bpf(4).security.mac.ifoff.other_enabledenables or disables traffic on all other interfaces.
One of the most common uses of mac_ifoff(4) is network monitoring in environments where network traffic must be blocked during boot. Another use is writing scripts that automatically block network traffic when applications such as security/aide discover new or changed files in protected directories.
MAC IP Address Access Control List Policy
Module name: mac_ipacl.ko
Kernel configuration line: options MAC_IPACL
Boot option: mac_ipacl_load="YES"
The mac_ipacl(4) policy allows a host to restrict the ability of VNET(9) jails to set IPv4 and IPv6 addresses using the sysctl(8) interface. When the default policy is enforced, all IP addresses for jails are denied.
The following sysctl tunable parameters are available:
security.mac.ipacl.ipv4enforces mac_ipacl for IPv4 addresses (default: 1).security.mac.ipacl.ipv6enforces mac_ipacl for IPv6 addresses (default: 1).security.mac.ipacl.rulesIP address access control list, format isjid,allow,interface,addr_family,IP_addr/prefix[@jid,...]. Whereallowis 1 for allow, 0 for deny;interfaceleft empty matches all interfaces;addr_familyisAF_INETorAF_INET6;prefixof -1 means a single IP, non-negative value means a subnet.
When multiple rules apply to the same IP address, the rule defined later in the list determines the final result.
MAC Port Access Control List Policy
Module name: mac_portacl.ko
Kernel configuration line: options MAC_PORTACL
Boot option: mac_portacl_load="YES"
The mac_portacl(4) module is used to restrict local TCP and UDP port binding, allowing non-root users to bind to specified privileged ports below 1024.
Once loaded, this module enables the MAC policy on all sockets. The following tunable parameters are provided:
security.mac.portacl.enabledfully enables or disables this policy.security.mac.portacl.port_highsets the highest port number protected by mac_portacl(4).security.mac.portacl.suser_exemptwhen set to a non-zero value, exemptsrootfrom this policy.security.mac.portacl.autoport_exemptwhen set to a non-zero value (default), allows applications to use port 0 for automatic allocation, bypassing rule checking.security.mac.portacl.rulesspecifies the policy as a text string, formatrule[,rule,…], containing as many rules as needed, each in the formatidtype:id:protocol:port.idtypeshould beuidorgid;protocolcan betcporudp;portis the port number allowed for the specified user or group to bind. User ID, group ID, and port parameters use numeric values only.
By default, ports below 1024 can only be used by privileged processes running as root. To allow mac_portacl(4) to permit non-privileged processes to bind to ports below 1024, configure as follows:
Warning
Setting both
net.inet.ip.portrange.reservedlowandnet.inet.ip.portrange.reservedhighto0completely removes the kernel-level privileged port protection mechanism, meaning ports 1-1023, which were originally only bindable byroot, are no longer subject to any kernel restrictions. The implication of this configuration is: replacing traditional UNIX privileged port protection entirely with mac_portacl's rule-level protection.If the mac_portacl module is not loaded for any reason, is disabled (
security.mac.portacl.enabled=0), or the rule configuration is incorrect, the system will revert to a state where all users can bind to any port — this includes critical service ports such as SSH (22), HTTP (80), and HTTPS (443), which may lead to service hijacking or privilege escalation attacks. Ensure thatmac_portaclis always reliably loaded and that rules are complete.
To prevent root from being affected by this policy, set security.mac.portacl.suser_exempt to a non-zero value:
Allow the www user with UID 80 to bind to port 80 without root privileges:
The following example allows the user with UID 1001 to bind to TCP ports 110 (POP3) and 995 (POP3s):
MAC NTPD Policy
Module name: mac_ntpd.ko
Kernel configuration line: options MAC_NTPD
Boot option: mac_ntpd_load="YES"
The mac_ntpd(4) policy module allows ntpd(8) to run as a non-root user, granting the following privileges to processes running under UID 123 (the ntpd user):
PRIV_ADJTIME
Adjust system time
PRIV_CLOCK_SETTIME
Set system clock
PRIV_NTP_ADJTIME
NTP time adjustment
PRIV_NETINET_RESERVEDPORT
Bind privileged ports
PRIV_NETINET_REUSEPORT
Reuse ports
When ntpd(8) is started with -u <user>[:group], it first initializes with root privileges and then drops privileges to the specified user. This policy ensures that ntpd can still perform the privileged operations required for time synchronization after dropping privileges.
The following sysctl tunable parameters are available:
security.mac.ntpd.enabledenables the mac_ntpd policy (default: 1).security.mac.ntpd.uidnumeric UID of the ntpd user (default: 123).
MAC Partition Policy
Module name: mac_partition.ko
Kernel configuration line: options MAC_PARTITION
Boot option: mac_partition_load="YES"
The mac_partition(4) policy places processes into specific "partitions" based on their MAC labels. Most configuration for this policy is done using setpmac(8). sysctl tunable parameter:
security.mac.partition.enabledenables MAC process partition enforcement.
When this policy is enabled, users can only view their own processes and other processes within their partition, and cannot use utilities outside their partition scope. For example, users in the insecure class cannot access top and many commands that require spawning processes.
This example adds top to the label set for the insecure class of users. All processes of the insecure class remain within the partition/13 label:
Display partition labels and process list:
Display partition labels for another user's processes and that user's currently running processes:
Unless mac_seeotheruids(4) is loaded, users can see processes in the root label.
MAC Priority Policy
Module name: mac_priority.ko
Kernel configuration line: options MAC_PRIORITY
Boot option: mac_priority_load="YES"
The mac_priority(4) policy module grants scheduling priority privileges based on group(5) group membership. Users or processes in the realtime group (GID 47) are allowed to run threads and processes at real-time scheduling priority; users or processes in the idletime group (GID 48) are allowed to run at idle scheduling priority.
The realtime policy grants the following kernel privileges:
PRIV_SCHED_RTPRIO— Real-time priorityPRIV_SCHED_SETPOLICY— Set scheduling policy
The idletime policy grants the following kernel privilege:
PRIV_SCHED_IDPRIO— Idle priority
With realtime enabled, privileged users can use rtprio(1) to start processes at real-time priority; with idletime enabled, idprio(1) can be used to start processes at idle priority. Applications can adjust priority through the rtprio(2) system call.
The following sysctl tunable parameters are available:
security.mac.priority.realtimeenables the realtime policy (default: 1).security.mac.priority.realtime_gidnumeric GID of the realtime group (default: 47).security.mac.priority.idletimeenables the idletime policy (default: 1).security.mac.priority.idletime_gidnumeric GID of the idletime group (default: 48).
MAC Multilevel Security Module
Module name: mac_mls.ko
Kernel configuration line: options MAC_MLS
Boot option: mac_mls_load="YES"
The mac_mls(4) policy enforces strict information flow control, managing access between subjects and objects in the system.
In an MLS environment, each subject or object's label contains a "clearance" level and compartments. The clearance level can reach thousands, making it extremely labor-intensive to configure each subject or object individually. To reduce management burden, this policy includes three built-in labels: mls/low, mls/equal, and mls/high:
The
mls/lowlabel represents a low clearance level, cannot access higher-level information, and prevents higher-level objects from writing or passing information to lower levels.The
mls/equallabel applies to objects that need to be exempt from the policy.mls/highis the highest clearance level. Objects assigned this label dominate all other objects in the system, but information cannot be leaked to lower-level objects.
MLS provides:
Hierarchical security levels, accompanied by a set of non-hierarchical categories;
The fixed rule "no read up, no write down" — subjects can read objects at the same or lower level, but cannot read higher-level objects; similarly, subjects can write to objects at the same or higher level, but cannot write to lower-level objects;
Confidentiality (prevention of improper data disclosure);
A design foundation that supports processing data at multiple sensitivity levels concurrently in the same system without leaking information between confidential and classified levels.
The following sysctl tunable parameters are available:
security.mac.mls.enabledenables or disables the MLS policy.security.mac.mls.ptys_equalmarks all pty(4) devices asmls/equalupon creation.security.mac.mls.revocation_enabledrevokes access to objects after a label changes to a lower grade.security.mac.mls.max_compartmentssets the maximum number of compartment levels allowed in the system.
MLS labels are managed using setfmac(8). To assign a label to an object:
Get the MLS label of the file test:
A master policy file can also be created in the /etc/ path, specifying MLS policy information for processing by setfmac.
When using the MLS policy module, administrators need to plan the flow of sensitive information. The default block read up block write down sets all objects to a low level: everything is accessible, and administrators gradually increase information confidentiality.
Beyond the three basic labels, administrators can group users and groups as needed to block information flow. Using descriptive terms (such as Confidential, Secret, and Top Secret) to view clearance level information may be more intuitive. Some administrators establish different groupings by project level. Regardless of the classification method, careful planning is required before implementing a restrictive policy.
Typical application scenarios for the MLS policy module include e-commerce web servers, file servers storing critical corporate information, and financial institution environments.
MAC Biba Module
Module name: mac_biba.ko
Kernel configuration line: options MAC_BIBA
Boot option: mac_biba_load="YES"
The mac_biba(4) module loads the MAC Biba policy. This policy is similar to the MLS policy, but the information flow rules are exactly reversed: Biba prevents sensitive information from flowing downward, while MLS prevents sensitive information from flowing upward.
In a Biba environment, each subject or object is assigned an "integrity" label. The label consists of a hierarchical grade and non-hierarchical components. Higher grades indicate higher integrity.
The supported labels are biba/low, biba/equal, and biba/high:
biba/lowis the lowest integrity an object or subject can have. Setting this label on an object or subject prevents it from writing to objects or subjects labeledbiba/high, but read access is unrestricted.biba/equalis only used for objects that need to be exempt from the policy.biba/highallows writing to objects with lower labels, but prevents reading from objects with lower labels. It is recommended to assign this label to objects that affect the overall integrity of the system.
Biba provides:
Hierarchical integrity levels, accompanied by a set of non-hierarchical integrity categories;
The fixed rule "no write up, no read down", the opposite of MLS — subjects can write to objects at the same or lower level, but cannot write to higher-level objects; similarly, subjects can read objects at the same or higher level, but cannot read lower-level objects;
Integrity assurance (prevention of improper data tampering);
Based on integrity levels rather than MLS sensitivity levels.
The following tunable parameters control the Biba policy:
security.mac.biba.enabledenables or disables Biba policy enforcement.security.mac.biba.ptys_equaldisables the Biba policy on pty(4) devices.security.mac.biba.revocation_enabledrevokes access to objects after a label changes to one that dominates the subject.
Access to Biba policy settings on system objects uses setfmac and getfmac:
Integrity (as distinct from sensitivity) is used to ensure that information is not controlled by untrusted parties, including information transmitted between subjects and objects. It ensures that users can only modify or access information they are explicitly authorized to access. The mac_biba(4) security policy module allows administrators to configure which files and programs users can view and invoke, while ensuring that these programs and files are trusted for that user.
During the initial planning phase, administrators need to divide users into grades, levels, and compartments. When this policy module is enabled, the system defaults to a high label, and administrators configure different grades and levels for different users. A good planning approach is to organize by topic rather than clearance level. For example, only allow developers to have modification privileges for the source code repository, source code compilation programs, and other development utilities; other users (such as testers, designers, or end users) are only allowed read access.
Lower-integrity subjects cannot write to higher-integrity subjects; higher-integrity subjects cannot list or read lower-integrity objects. Setting labels to the lowest possible grade may make objects inaccessible to subjects. Suitable environments for this security policy module include restricted web servers, development and testing machines, and source code repositories; less suitable scenarios include personal workstations, routers, or network firewalls.
MAC Low-watermark Module
Module name: mac_lomac.ko
Kernel configuration line: options MAC_LOMAC
Boot option: mac_lomac_load="YES"
Unlike the MAC Biba policy, mac_lomac(4) allows access to lower-integrity objects, provided that integrity rules are not violated and the subject's integrity level is lowered first.
The Low-watermark integrity policy works essentially the same as Biba, with the difference being the use of floating labels: subject demotion is supported through an auxiliary grade compartment. The auxiliary compartment format is [auxgrade]. The syntax for assigning a policy with an auxiliary grade is lomac/10[2], where 2 is the auxiliary grade.
This policy relies on universally labeling all system objects with integrity labels, allowing subjects to read from low-integrity objects and then lower the subject's label, using [auxgrade] to prevent subsequent writes to high-integrity objects. Compared to Biba, this policy offers greater compatibility and requires less initial configuration.
As with Biba and MLS policies, use setfmac and setpmac to place labels on system objects:
The auxiliary grade low is a feature unique to the LOMAC policy.
User Lockdown
This example envisions a small storage system with fewer than fifty users. Users can log in, store data, and access resources.
In this scenario, the mac_bsdextended(4) and mac_seeotheruids(4) policy modules can coexist, both hiding user processes and blocking access to system objects.
First, add the following to /boot/loader.conf:
Add the following lines to /etc/rc.conf to activate the mac_bsdextended(4) security policy module:
During system initialization, the default rules from /etc/rc.bsdextended will be loaded. The default entries may need modification. This computer is only used for user services; all entries except the last two can be left commented out to enforce default loading of user-owned system objects.
Add the required users to this computer and reboot. For testing, log in as different users on two separate consoles. Run ps aux to check if other users' processes are visible. Verify that running ls(1) on other users' home directories fails.
Do not test as root unless specific sysctl settings have been modified to prevent superuser access.
When adding new users, their mac_bsdextended(4) rules will not appear in the rule set list. To quickly update the rule set, first unload the security policy module, then reload it using kldunload(8) and kldload(8).
Troubleshooting
This section discusses common configuration errors and their solutions.
The multilabel Flag Fails to Remain Enabled on the Root (/) Partition
multilabel Flag Fails to Remain Enabled on the Root (/) PartitionIf the multilabel flag fails to remain enabled on the root (/) partition, the following steps can resolve this temporary error:
Edit /etc/fstab and set the root partition to
ro(read-only).Reboot into single-user mode.
Run the command
tunefs -l enableon /.Immediately run
mount -urw /, and changeroback torwin /etc/fstab.Reboot the system to normal mode.
Carefully check the
mountoutput to confirm that the root file system has themultilabelflag properly set.
Unable to Start Xorg
After establishing a secure environment with MAC, Xorg cannot start. The cause may be the MAC partition policy or incorrect label settings in a MAC label policy. Debugging steps are as follows:
Check the error messages. If the user is in the
insecureclass, thepartitionpolicy may be the issue. Try restoring the user class to thedefaultclass and rebuild the database usingcap_mkdb.Carefully check the label policy settings for the user, Xorg, and /dev entries.
If neither resolves the issue, the error messages and environment description can be sent to the FreeBSD general questions mailing list.
Error When Switching Users
When a user switches from root to another user in the system, an error message _secure_path: unable to stat .login_conf may appear. This message typically occurs when the user's label is higher than the target user being switched to. For example, if joe's default label is biba/low and root's label is biba/high, root cannot view joe's home directory because the Biba integrity model does not allow root to view objects at a lower integrity level — this occurs regardless of whether root uses su to switch to joe.
Root User Not Recognized
The system no longer recognizes root. In this case, whoami returns 0, and su returns who are you?.
This situation may be caused by the label policy being disabled via sysctl(8) or the policy module being unloaded. If the policy has been disabled, the login capability database needs to be reconfigured: carefully check /etc/login.conf to ensure all label options have been removed, then rebuild the database using cap_mkdb.
This can also occur when the policy restricts access to /etc/master.passwd. This is typically because the administrator changed the file under a label that does not conform to the system's general policy. In this case, the system reads user information, but access is blocked because the file inherited the new label. Recovery should be possible after disabling the policy using sysctl(8).
Exercises
The FreeBSD MAC framework uses a modular design, with the kernel implementing different mandatory access control policies through
mac_*.kopolicy modules. List at least 4 FreeBSD built-in MAC policy modules and briefly describe their application scenarios.What is the fundamental difference between the MAC framework and traditional Discretionary Access Control (DAC)?
When enabling a MAC policy module (such as
mac_portacl) in FreeBSD, it is typically necessary to modify /boot/loader.conf and reboot the system. Write a complete configuration example and explain how to verify currently loaded MAC policy modules without rebooting.
Last updated