# cat /dev/two

To content | To menu | To search

Tag - selinux

Entries feed - Comments feed

2012-09-29

An SELinux constraint violation (p 4 of 5)

This is part 4 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 give mount_t the attribute mcsreadall

Excellent, so we could grant mount_t the attribute 'mcsreadall' and our constraint violation would disappear. At this point, it is always a good idea to pause and consider the ramifications of a policy change, does the grant make sense, is it too broad or too narrow?

To answer that, we need to start off by getting a better idea of what other permissions the attribute 'mcsreadall' would grant mount_t. All we know right now is that it would permit "dir { search read ioctl lock }".

Searching through the policy turned up three additional grants:

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

mlsconstrain fifo_file { open }
    (( h1 dom h2 ) or ( t1 == mcsreadall ) or
     (( t1 != mcsuntrustedproc ) and ( t2 == domain )));

mlsconstrain { lnk_file chr_file blk_file sock_file } { getattr read ioctl }
    (( h1 dom h2 ) or ( t1 == mcsreadall ) or
     (( t1 != mcsuntrustedproc ) and (t2 == domain)));

Unsurprisingly, mcsreadall does roughly what one would assume, it allows processes of that type to preform all read operations on files, directories, fifos, links, character devices, block devices, and sockets. That is a little more access than we actually require in this case, mount has little need to read the content of a file outside its category, it would be nice to narrow the scope a bit. Unfortunately that brings us to a fork in the road, do we grant 'mount_t' access via the mcsreadall attribute, or do we create a different way to grant mount_t the access it needs?

It would certainly be possible to create something like 'mcssearchalldir' by adding the attribute, splitting up the constraints, adding the appropriate interface, and applying the new attribute to mount_t via the new interface. The question is, does the security benefit of such a change outweigh the added complexity, including the additional maintenance burden?

Adding additional granularity to the policy is a big question, a question probably best discussed with security experts or decided by the policy maintainer since making another attribute for constraint would practically require forking the policy. So, let's side step that one for now and assume granting mount_t the mcsreadall attribute constitutes an acceptable risk.

Next up, part 5: Giving mount_t the mcsreadall attribute.

2012-09-26

An SELinux constraint violation (p 3 of 5)

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.

2012-09-22

An SELinux constraint violation (p 2 of 5)

This is part 2 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.

An example constraint violation issue

In the audit2allow and audit2why output examples, there is an AVC which happens to be a constraint violation issue. Here it is again:

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

The run up to hitting this is not too interesting, but a little background may be relevant:

autofs is being instructed to mount a particular NFS share with mountpoint labeling. Not just basic mount point labeling, but a category restricted context. That is visible in the AVC, where the target context is "system_u:object_r:nfs_t:s0:c20".

This problem originally presented itself when a fully functional test system was patched from RHEL6.2 to RHEL6.3 and rebooted. All of a sudden autofs started returning "No such file or directory". After turning on debugging for autofs by inserting the following into /etc/sysconfig/autofs

setting OPTIONS="--verbose --debug"

and restarting the service, the logs clearly showed the problem

automount[1250]: mount_mount: mount(nfs): calling
    mkdir_path /somedir/somemount
automount[1250]: mount_mount: mount(nfs): calling mount -t nfs4 -s
    -o port=2049,rw,context=system_u:object_r:nfs_t:s0:c20
    an_nfs_server.local:/export/somedir /somedir/somemount
automount[1250]: >> mount.nfs4: access denied by server while
    mounting an_nfs_server.local:/export/somedir
automount[1250]: mount(nfs): nfs: mount failure
    an_nfs_server.local:/export/somedir on /somedir/somemount
automount[1250]: dev_ioctl_send_fail: token = 28
automount[1250]: failed to mount /somedir/somemount
automount[1250]: st_expire: state 1 path /somedir

In this case, the server had not been touched, so it made little sense that it would all of a sudden start denying a valid mount request. A lot of possibilities existed since a many components were updated between a fully patched RHEL6.2 and a RHEL6.3 install, and I had already found significant (but unrelated) issues with a number of the NFS stack modifications. However, before diving into a rabbit hole of debugging NFS, I tried running the mount outside of autofs, using the exact options from automount. When that worked, the problem scope shrank significantly.

I will leave out the irrelevant details. In the end, it was starting to feel like an selinux denial issue, but nothing was showing up in /var/log/audit/audit.log or /var/log/debug. I used semodule to rebuild the policy without the dontaudit rules

$ semodule -DB

and sure enough, the AVC listed above showed up. A trip through audit2allow made it clear this was not going to be a two minute fix.

Next up, part 3: Locating the troublesome constraint.

- page 2 of 5 -