TrustedBSD – MAC BIBA Policy

We create open-source because we love it, and we share our finding so everyone else can benefit as well.


TrustedBSD – MAC BIBA Policy

For our 3rd part of the tutorial, we are going to cover one of the MAC BIBA policy. This policy controls the upward flow of information. In other words, we can restrict access based on a user or process. We will look at how to add our policy, and how to alter it to our needs.

This article references the previous two articles, so you may want to review the basics before jumping into this article.

TrustedBSD – Mandatory Access Control

TrustedBSD – MAC Processes


First, we need to make sure that the module loads. We do this by adding it to the loader, while also keeping some network interfaces from being blocked.

Add these lines to the /boot/loader.conf:


…and for our network interfaces:



security.mac.biba.trusted_interfaces="dc0 lo0"

The first interface OID, allows all interfaces to be used by the system, and the users. If we want to restrict some interfaces, we can use the 2nd OID to do so. We simply list the interfaces we want to allow access, with a space in between.

Next, we reboot into single-user mode to enable labeling.

# tunefs -l enable /
 # exit

Basic Understanding of MAC BIBA

Now that we have our system set up to use the MAC BIBA module, let’s see how this works. First we need to make a MAC BIBA test user. I will of course continue to use my faithful “MacUser”. Be sure that /sbin and /usr/sbin are in your user’s path, otherwise use ‘whereis‘ when trying to find commands that aren’t found in your path.

Now we need to alter the label in out login.conf (reffer to Part 2 on how to apply classes and labels):


Let’s first take a look at the label we added: biba/low(low-low). Normally, we would use biba/low for our label, but just to show you there is more to it, we added the “(low-low)”. First things first, the BIBA module has three special labels to simplify the labeling process; biba/high, biba/low, and biba/equal. Biba/high is the highest of all labels, and will always be greater than all.

The biba/high level is also the default label for basically everything on the filesystem, and the default user class. Biba/low, of course, is the lowest of all labels. Last, biba/equal, is the label to omit a subject(user), or object(file/process), from the MAC BIBA module. If the subject’s integrity is equal the object’s integrity level, then the subject has full control. When the subject’s integrity level is greater than the object’s, the subject will loses read access, but retain write access. If the subject’s integrity level is less than the object’s, the subject can read, but not write. Now, let’s see how this works.

> whoami
 > getpmac
# getpmac
 # touch /home/MacUser/test
 # touch /home/MacUser/test2
 # chown MacUser:MacUser /home/MacUser/test
> ls -lZ
 -rw-r--r-- 1 MacUser MacUser biba/high 0 Jul 31 09:59 test
 -rw-r--r-- 1 root MacUser biba/high 0 Jul 31 09:59 test2
> cat test
 > echo test > test
 test: Permission denied.
 > rm test
 override rw-r--r-- MacUser/MacUser for test? y
 rm: test: Permission denied

Setting File Permissions

So we first check our user’s BIBA integrity level with getpmac. We then create our test files, and set ownership with our root-type user. Just like ps, ls has the “Z” option to show MAC labels. Both files are given the default label of biba/high. We first want to test out ability to read the file and the our ability to write as our user. As we can see, we can read the file, but cannot write to the file. Not only that, we cannot remove the file, and to add, we see that rm sees that the permissions are higher, and asks us if we would like to override the permissions. Of course, we cannot.

# setfmac biba/low /home/MacUser/test
 # cat /home/MacUser/test
 cat: /home/MacUser/test: Permission denied
> cat test
 > echo testing > test
 > rm test
 rm: test: Permission denied

Next, we change the label of the test file to biba/low with another tool, setfmac. Setfmac works by setting the label to the file(s), in that order:

 setfmac [label] [file1] [file2]

Now that it is not equal to the integrity of the root-type user (biba/high), that user cannot read the file. As our regular user, we have full access to the file since its integrity is now equal to our user’s. We can see right after, we still cannot remove the file.

# setfmac biba/equal /home/MacUser/test*
 # cat /home/MacUser/test1/test
> cat test
 > echo testingagain >> test
 > echo testing > test2
 test2: Permission denied.
 > rm test
 rm: test: Permission denied

Last, we test the biba/equal label on the file. The object, or the file, now ignores the policy, and allows all users the ability to read and write to the file, regardless of the label, because it is now equal to all. Now wait, we can’t write to the test2 file, nor can we remove test. Before you tell me this is a dirty trick, I have to point this out over and over again so that we don’t end up confused with the policies. Remember, the MAC policies overlay the UNIX DAC permissions. What about our ‘ls’ output? Who owned test2? That’s right root still owns it.

# setfmac -R /home/MacUser biba/low
> rm test
# cd /home/MacUser
 /home/MacUser: Permission denied

So what about the test file we can’t remove? Do you remember that I said that biba/high is the default integrity label for objects? MacUser’s home directory was one of those objects. After we set MacUser’s home directory recursively to biba/low, we can now delete the test file. Then we try to change to the home directory with our root-type user. What? Root doesn’t have access? While root would have access to change the label, we now have the ability to alienate root from the list of all-knowing, snooping admins.

Setting Labels

Before we get into the more complicated policy integrity levels, we need to cover setting labels, and the access we have. Remember the range in the level surrounded in parethesis? This range of integrity levels is used for the processes we use. When we want to have a process access an object of a different integrity level, we can do so if that integrity level is in our range of levels. Still confused? That’s ok, let’s take a look at a few examples.

# getpmac
> getpmac

Ok, let’s look at our user’s labels, and focus on the ranges. The root type user has low to high. The regular user has low-low. Now, if you remember in the last tutorial, we used “setpmac” to set the label for a process. We are going to do the same thing here, except we are going to set the label as we initiate the process. Continuing from the examples before, we’ll start off with test files again.

> ls -lZ
 total 8
 -rw-r--r-- 1 root MacUser biba/low 0 Jul 31 12:47 test2
 -rw-r--r-- 1 MacUser MacUser biba/low 0 Jul 31 13:04 test3
 -rw-r--r-- 1 MacUser MacUser biba/low 0 Jul 31 13:05 test4
 -rw-r--r-- 1 MacUser MacUser biba/low 0 Jul 31 13:05 test5

In the MacUser home directory I simply touched three new files to the directory as our regular user.

# setpmac biba/low setfmac biba/high /home/MacUser/test4

To explain what we just did, remember that we do not have access to physically go into the directory. Since we know what file we want to change, we can still write a label to it when making the process equal to the object integrity. If we tried to do this without setting the process integrity, we would have failed, and gained an error. So, now that we have changed the label of that file, let’s take a look at it.

# setpmac biba/low ls -lZ MacUser/
 total 8
 -rw-r--r-- 1 root MacUser biba/low 0 Jul 31 12:47 test2
 -rw-r--r-- 1 MacUser MacUser biba/low 0 Jul 31 13:04 test3
 -rw-r--r-- 1 MacUser MacUser biba/high 0 Jul 31 13:09 test4
 -rw-r--r-- 1 MacUser MacUser biba/low 0 Jul 31 13:05 test5

What we are doing is simply making the process seem like a user with biba/low integrity. As a note, to be complete, you can use the biba/equal to bypass any label, but let’s not get into that habit. You’ll see why later. So, what about our regular user? Is it restricted to where it can’t do anything at all? Well, it is quite limited, and it would be futile to even bother with the setpmac command, since it doesn’t have a range to use at all, but there are a few things to keep in mind. First, any object in an object that is the same level of the user, can be changed to the integrity level of the user.

> setfmac biba/low test4
 > ls -lZ
 total 8
 -rw-r--r-- 1 root MacUser biba/low 0 Jul 31 12:47 test2
 -rw-r--r-- 1 MacUser MacUser biba/low 0 Jul 31 13:04 test3
 -rw-r--r-- 1 MacUser MacUser biba/high 0 Jul 31 13:09 test4
 -rw-r--r-- 1 MacUser MacUser biba/low 0 Jul 31 13:05 test5

Since the home directory is still marked with biba/low, the user was able to change the integrity level to a matching level. If it was still biba/high, we would encounter an error like so.

setfmac: mac_set_link(test4, biba/low): Operation not permitted

Although the user has full control, it cannot change it to a higher integrity level. If the user had an intregrity level range of (low-high), we can use the setpmac command to change to biba/high, or even biba/equal. We could essentially set a user to biba/low(low-high), and set root type users to biba/high(high-high). This way we only permit root to do admin, and users don’t have to worry about a nosy admin.

Interfaces and MAC BIBA

While we allowed intrefaces to work, we have to understand that doesn’t mean that everybody can use them.

> ifconfig dc0
 dc0: flags=8843<up,broadcast,running,simplex,multicast> mtu 1500
 inet netmask 0xffffff00 broadcast
 ether 00:04:5a:6f:1d:0c
 maclabel biba/high(high-high)
 media: Ethernet autoselect (100baseTX )
 status: active

We see that the default label, like everything else is biba/high, but the behaviour that we see is a bit different. The first part of the label handles the allowed labels for receiving traffic, while the range tells the interface what traffic can be transmitted.

> ping
 PING ( 56 data bytes
 ping: sendto: Permission denied

As we can see, we can’t do either from the MacUser. Changing the transmit should help.

# ifconfig dc0 maclabel "biba/high(low-high)"
> ping
 PING ( 56 data bytes

Well, we can transmit, but we can’t see anything coming back of course. We now need to change the transmit permissions, but since the default user label is biba/high, we will just set it to equal.

# ifconfig dc0 maclabel "biba/equal(low-high)"

Now we have the ability to ping transmit, and receive the incoming replies.

More Advanced Policy Integrity Levels

Now that we have the basics down, it’s time for us to start looking at setting integrity levels by hand, and using numerical values.
Let’s first take a look at the numerical labels.


Instead of using special labels that say, greater/less than all, we are going to set our own grades of integrity, and a set of compartments that a class can access. Let’s break that last label down into descriptions.


Let’s change our labels a bit, and make a second one of top of that. I’m going to assign the class “testing” with MacUser, and “testing2” with MacUser2.



Now, let’s observe how things work out.

Could not chdir to home directory /home/MacUser: Permission denied
 > getpmac
 getpmac: Command not found.
 > /usr/sbin/getpmac
 > /usr/sbin/getfmac /home/MacUser
 /home/MacUser: biba/low
 /usr/sbin/setpmac biba/low /usr/sbin/setfmac biba/5 MacUser> ls -lZ
 total 10
 drwxr-xr-x 4 MacUser MacUser biba/5 512 Jul 31 14:15 MacUser
 drwxr-xr-x 2 MacUser2 MacUser biba/high 512 Jul 6 14:49 MacUser2

First we see that we couldn’t even get into our own directory, and due to that, we lost our ability to read our .cshrc, which holds our path. So, we then get the label of our user and the directory by using the full path of getpmac, and getfmac. Now that we know what the integrity level is, we change the label of our home directory to match our new label, without the containers.

2> setpmac biba/5 setfmac biba/6 MacUser2/

Reviewing Changes

If we logout and log back in we’ll be able to see the effects of our changes.

2> chmod 775 /home/MacUser2
> cd /home/MacUser2
 > setpmac biba/6 touch test
 > setpmac biba/6 touch test2
 > setpmac biba/6 touch test3
 > setpmac biba/6 chmod 664 *
 > setpmac biba/6 setfmac biba/5:3 test
 > setpmac biba/6 setfmac biba/5:4 test2
 > setpmac biba/6 setfmac biba/5:2+3 test3
 > ls -lZ
 total 4
 -rw-rw-r-- 1 MacUser MacUser biba/5:3 0 Jul 31 17:22 test
 -rw-rw-r-- 1 MacUser MacUser biba/5:4 0 Jul 31 15:03 test2
 -rw-rw-r-- 1 MacUser MacUser biba/5:2+3 0 Jul 31 15:03 test3
2> ls -lZ
 ls: test: Permission denied
 ls: test2: Permission denied
 ls: test3: Permission denied
 total 0

Just to skim the surface, we created a few files in MacUser2’s home directory. We then changed the labels to grade 5, with compartment 2+3 and 2+3+4. The effective grade of MacUser is 5, while MacUser2’s effective grade is 6. As you can see, since it’s grade is larger than the grade of the objects, it cannot read them. So, we need to alter our presence to even view the details of the files.

2> setpmac biba/5 ls -lZ
 total 4
 -rw-rw-r-- 1 MacUser MacUser biba/5:3 0 Jul 31 17:22 test
 -rw-rw-r-- 1 MacUser MacUser biba/5:4 0 Jul 31 15:03 test2
 -rw-rw-r-- 1 MacUser MacUser biba/5:2+3 0 Jul 31 15:03 test3

Now, notice that we didn’t specify the compartment for our process. Since we can read, and view files being at a lower integrity, setting to the integrity grade without the compartments shows us the files and their attributes. If we set the matching compartments of the files as well, we could have full access.

Now, the purpose of the compartments is to allow certain users in a grade to be able to have access to certain files on a “need to know” basis. If the subject (user/process), meets all of the qualifications, they can have full access to the file. You could set the compartments, and once again fork the permissions across a single grade. The compartment feature has the ability to have up to 256 compartments by default. So, in retrospect, you could have an infinite ability to isolating the ability of each user if needed.

MAC_BIBA Other Important OIDs

security.mac.biba.interfaces_equal: 0|1 // set interfaces to biba/equal (Default 0 off)
security.mac.biba.ptys_equal: 0|1       // set ptys to biba/equal (Default 0 Off)
security.mac.biba.max_compartments: 256 // max compartments (Default 256. Must be set at boot time)
security.mac.biba.label_size: 112       // (Default 112. Must be set at boot time)


As we can see, the biba module can be used to help restrict users even more, making sure that information doesn’t go anywhere it shouldn’t. While we only skimmed the surface of the advanced features of the module, we will see them in a later tutorial. As a side note, be very careful with your labels, and always test before you put them into serious system play. Until next time, enjoy, and have fun!

Comments: 2

  1. Daniel says:

    Whenever I add the following below to my /etc/login.conf file and rebuild the database with cap_mkdb /etc/login.conf it doesn’t work.


    • dbrown says:

      Hey Daniel!

      The parser is incredibly particular about the placement of : and \ in the login.conf, and I do believe there needs to be a \ after “testing:” (looks like it was missing in the post).

Add your comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.