This is part 3 of a 5 part post on identifying and fixing an· SELinux constraint violation. If you have not already read the previous parts, you may want to start at the beginning.

Preparing to locate the troublesome constraint

audit2why pointed us to "the policy sources in policy/constraints (general), policy/mcs (MCS), and policy/mls (MLS)." That is all well and good, but first we have to actually get to the policy sources in a format we can read them.

This can and should be done as a regular user (not root)

$ cd /tmp

# grab the current srpm
$ wget http://ftp.redhat.com/redhat/linux/enterprise/6Server/en/os/SRPMS/selinux-policy-3.7.19-155.el6_3.src.rpm

# setup a temporary rpm build root location
$ cat << EOF > ~/.rpmmacros
%_topdir /tmp
%_tmppath   /tmp/tmp
EOF

# install the srpm to have it do the unpacking for us
# (don't worry about 
#   "warning: group mockbuild does not exist - using root")
$ rpm -ivh selinux-policy-3.7.19-155.el6_3.src.rpm

# have rpm do all of the patching for us
$ cd /tmp/SPECS
$ rpmbuild -bp selinux-policy.spec

# change into the policy source we just prepared
$ cd /tmp/BUILD/serefpolicy-3.7.19

# and see the files audit2why was directing us to
$ ls policy
    constraints
    flask/
    global_booleans
    global_tunables
    mcs
    mls
    modules/
    policy_capabilities
    rolemap
    support/
    users

Actually locating the troublesome constraint

Well, audit2why said the constraint was in policy/constraints, policy/mcs, or policy/mls. This system was running MCS, not MLS, so that left policy/constraints and policy/mcs. The former is almost entirely focused on user based access control (UBAC) which did not seem likely for a number of reasons, among them; our source context was the same selinux user as our target context.

AVC again for easy reference:

avc:  denied  { search } for  pid=1597
comm="mount.nfs4" name="" dev=0:16 ino=2
scontext=system_u:system_r:mount_t:s0
tcontext=system_u:object_r:nfs_t:s0:c20 tclass=dir

Onward, into policy/mcs. The AVC was on a directory search operation, so let's start there. In the entire file, only one stanza restricts search, that made it easy to narrow things down.

mlsconstrain dir { search read ioctl lock }
    (( h1 dom h2 ) or ( t1 == mcsreadall ) or
    (( t1 != mcsuntrustedproc ) and (t2 == domain)));

So this is our troublesome constraint, but it is not like we can just strip it out. Doing so would irreparably harm the security provided by MCS. Fortunately, the policy already provided a way around the constraint. If the source context had the attribute 'mcsreadall', then it would be able to search directories even when the source did not dominate the target.

Next up, part 4: Preparing to give mount_t the attribute mcsreadall.