Switching policy types in Gentoo/SELinux

When you are running Gentoo with SELinux enabled, you will be running with a particular policy type, which you can devise from either /etc/selinux/config or from the output of the sestatus command. As a user on our IRC channel had some issues converting his strict-policy system to mcs, I thought about testing it out myself. Below are the steps I did and the reasoning why (and I will update the docs to reflect this accordingly).

Let’s first see if the type I am running at this moment is indeed strict, and that the mcs type is defined in the POLICY_TYPES variable. This is necessary because the sec-policy/selinux-* packages will then build the policy modules for the other types referenced in this variable as well.

test ~ # sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             strict
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              disabled
Policy deny_unknown status:     denied
Max kernel policy version:      28
 
test ~ # grep POLICY_TYPES /etc/portage/make.conf
POLICY_TYPES="targeted strict mcs"

If you notice that this is not the case, update the POLICY_TYPES variable and rebuild all SELinux policy packages using emerge $(qlist -IC sec-policy) first.

Let’s see if I indeed have policies for the other types available and that they are recent (modification date):

test ~ # ls -l /etc/selinux/*/policy
/etc/selinux/mcs/policy:
total 408
-rw-r--r--. 1 root root 417228 Dec 19 21:01 policy.27
 
/etc/selinux/strict/policy:
total 384
-rw-r--r--. 1 root root 392168 Dec 19 21:15 policy.27
 
/etc/selinux/targeted/policy:
total 396
-rw-r--r--. 1 root root 402931 Dec 19 21:01 policy.27

Great, we’re now going to switch to permissive mode and edit the SELinux configuration file to reflect that we are going to boot (later) into the mcs policy. Only change the type – I will not boot in permissive mode so the SELINUX=enforcing can stay.

test ~ # setenforce 0
 
test ~ # vim /etc/selinux/config
[... set SELINUXTYPE=mcs ...]

You can run sestatus to verify the changes, but be aware that – while the command does say that the mcs policy is loaded, this is not the case. The mcs policy is just defined as the policy to load:

test ~ # sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             mcs
Current mode:                   permissive
Mode from config file:          enforcing
Policy MLS status:              disabled
Policy deny_unknown status:     denied
Max kernel policy version:      28

So let’s load the mcs policy shall we?

test ~ # cd /usr/share/selinux/mcs/
test mcs # semodule -b base.pp -i $(ls *.pp | grep -v base | grep -v unconfined)

Next we are going to relabel all files on the file system, because the mcs policy adds in another component in the context (a sensitivity label – always set to 0 for mcs). We will also re-do the setfiles steps done initially while setting up SELinux on our system. This is because we need to relabel files that are “hidden” from the current file system because other file systems are mounted on top of it.

test mcs # rlpkg -a -r
Relabeling filesystem types: btrfs ext2 ext3 ext4 jfs xfs
Scanning for shared libraries with text relocations...
0 libraries with text relocations, 0 not relabeled.
Scanning for PIE binaries with text relocations...
0 binaries with text relocations detected.
 
test mcs # mount -o bind / /mnt/gentoo
test mcs # setfiles -r /mnt/gentoo /etc/selinux/mcs/contexts/files/file_contexts /mnt/gentoo/dev
test mcs # setfiles -r /mnt/gentoo /etc/selinux/mcs/contexts/files/file_contexts /mnt/gentoo/lib64
test mcs # umount /mnt/gentoo

Finally, edit /etc/fstab and change all rootcontext= parameters to include a trailing :s0, otherwise the root contexts of these file systems will be illegal (in the mcs-sense) as they do not contain the sensitivity level information.

test mcs # vim /etc/fstab
[... edit rootcontext's to now include ":s0" ...]

There ya go. Now reboot and notice that all is okay, and we’re running with the mcs policy loaded.

test ~ # id -Z
root:sysadm_r:sysadm_t:s0-s0:c0.c1023
test ~ # sestatus
SELinux status:                 enabled
SELinuxfs mount:                /sys/fs/selinux
SELinux root directory:         /etc/selinux
Loaded policy name:             mcs
Current mode:                   enforcing
Mode from config file:          enforcing
Policy MLS status:              enabled
Policy deny_unknown status:     denied
Max kernel policy version:      28

8 Comments

  1. Hinnerk van Bruinehsen

    Hi,

    I noticed it a while ago but seeing it here and now offers a possibility to ask:

    root:sysadm_r:sysadm_t:s0-s0:c0.c1023

    Why does root has a mls like label in mcs?
    Every other user on my systems has only :::s0 – is there a reason for this?

    WKR
    Hinnerk

  2. That’s a good question. The answer lays in the policy, as usual. The root SELinux user and system_u SELinux user are defined as having access to all categories (from c0 to c1023 by default on Gentoo systems) whereas other users by default only have access to the c0 category.

    If you run semanage login -l this should show up in the MCS/MLS range column.

    If your other SELinux users need access to other categories as well, you can you semanage again to modify this. However, as far as I know, only the system_u SELinux user really needs it (as it is used for differentiating on service level, like with sVirt). The root user has it as well for recovery purposes.

  3. Thistled

    Hi Sven, any idea why I can’t load the targeted policy?
    I have rebuilt all sec-pol packages since changing SELINUX_TYPE to targetted, but the command above fails.
    I tried to do this from
    /usr/share/selinux/targeted/
    “semodule -b base.pp -i $(ls *.pp | grep -v base | grep -v unconfined)
    libsepol.print_missing_requirements: apache’s global requirements were not met: type/attribute gds_db_port_t (No such file or directory).
    libsemanage.semanage_link_sandbox: Link packages failed (No such file or directory).
    semodule: Failed!”

  4. The gds_db_port_t type should be provided by the base module, so its weird that apache wouldn’t be able to link with it.

    Generally, if you get errors like that, try removing the offending packages at first in the listing, so try with “semodule -b base.pp -i $(ls *.pp | grep -v base | grep -v unconfined | grep -v apache)” and work from there.

    That, or try to remove apache.pp from your current module list (semodule -r) and retry.

  5. Thistled

    Thanks for the prompt reply Sven, it is mega appreciated.
    However, both suggestions fail.
    The first suggestion replies with the same error.
    The second suggestion replies with….
    “Error opening /etc/selinux/targeted/contexts/files/file_contexts.local: No such file or directory
    libsemanage.sefcontext_compile: sefcontext_compile returned error code 255. Compiling /etc/selinux/targeted/contexts/files/file_contexts.local
    Error opening /etc/selinux/targeted/contexts/files/file_contexts.local: No such file or directory
    libsemanage.sefcontext_compile: sefcontext_compile returned error code 255. Compiling /etc/selinux/targeted/contexts/files/file_contexts.local
    semodule: Failed!”
    This is true, I do not seem to have a file_contexts.local file. As I understand it, I have to use semanage fcontext in order to create this file. But I do not know what fcontext I should me managing.

    Could my problem stem from the fact my system is currently set up as “Strict”.
    It is impossible to change the targeted, and I do not know why.

  6. I’ve been seeing this as well, seems like the new utilities require the local file to be there already.

    Just touch the files (touch /etc/selinux/targeted/contexts/files/file_contexts.local) as root and you should be set.

  7. Dennis Freise

    libsepol.print_missing_requirements: apache’s global requirements were not met: type/attribute gds_db_port_t (No such file or directory).
    libsemanage.semanage_link_sandbox: Link packages failed (No such file or directory).
    semodule: Failed!

    I’m seeing this error too, can’t figure out why. When I exclude the apache module from semodule, all works out fine. But I need that module… I already filed a bug report, but could anybody share some light on this, please?

Leave a Reply

Your email address will not be published. Required fields are marked *