Understanding SELinux, Part 7

In Part 6, we introduced a new type, lfy_t, to our SELinux environment. To do this we created our own SELinux module called test and its version number was 1.0. Since the last article, my system has been upgraded and, currently, I am using Fedora Core 12.

To test the effects of the new module, let us create a sample index.html file in the DocumentRoot folder of Apache:

[root@vbg ~]# echo "The Art of Guard - Part VII " > /var/www/html/index.html
[root@vbg ~]# service httpd start

To check if all is fine, let us view the Web page using elinks:

[root@vbg ~]# elinks --dump http://localhost
   The Art of Guard - Part VII

This shows that all is indeed fine and Apache can serve our document on the website. Let us now change the type of index.html to lfy_t and see what happens:

[root@vbg ~]# chcon -t lfy_t /var/www/html/index.html
chcon: failed to change context of `/var/www/html/index.html' to `system_u:object_r:lfy_t:s0': Permission denied

We have received an error message! The SELinux policy on my system does not allow us to change the type of the file /var/www/html/index.html to lfy_t.

But what is the current type of /var/www/html/index.html? To check the security context of index.html, use the following command:

[root@vbg ~]# ls -lZ /var/www/html/index.html
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html

We can see that the default type allotted to this file (SELinux object) is httpd_sys_content_t. Why is it so? We did not specify the file type when creating it. Why did it take this particular type and not tmp_t or some other type?

By default, newly created objects and subjects take the type of their parent object and subject, respectively. Since the folder /var/www/html/ is of the type httpd_sys_content_t, any new files created under it will also get the same type, unless you want it otherwise. The same applies to processes (or ‘subject’ in SELinux terminology).

Since SELinux is not allowing us to change the security context of our file to lfy_t, we will need to write a few allow rules and include them in our policy. As discussed in the earlier article, the best way is to add these allow rules to our Policy Module.

But first we need to understand why exactly this action is being disallowed. Let us turn to the log files for help:

[root@vbg ~]# tailf /var/log/audit/audit.log

type=AVC msg=audit(1261193853.109:39): avc:  denied  { relabelto } for  pid=2293 comm="chcon" name="index.html" dev=sda2 ino=104970 scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=system_u:object_r:lfy_t:s0 tclass=file
type=SYSCALL msg=audit(1261193853.109:39): arch=c000003e syscall=188 success=no exit=-13 a0=1a660e0 a1=3dece15649 a2=1a67660 a3=1b items=0 ppid=1960 pid=2293 auid=500 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=1 comm="chcon" exe="/usr/bin/chcon" subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 key=(null)
type=USER_AUTH msg=audit(1261194789.950:40): user pid=2313 uid=500 auid=500 ses=1 subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 msg='op=PAM:unix_chkpwd acct="vbg" exe="/sbin/unix_chkpwd" hostname=? addr=? terminal=? res=success'

Now we can see from the AVC Denial message in the Audit Log that relabelto permission is denied to the source context unconfined_t (bash process—my shell) for the target context lfy_t. Going by our earlier discussion (in Part 5), we could create an allow rule for the above in our test.te file:

allow unconfined_t lfy_t : file { relabelto }

But will this solve the above-mentioned issue? Will not other SELinux denials crop up?

The important thing to remember is that SELinux permissive mode has been given for exactly this reason—troubleshooting. So let us take the system into permissive mode and see if any more errors occur:

[root@vbg ~]# getenforce
Enforcing
[root@vbg ~]# setenforce 0
[root@vbg ~]# getenforce
Permissive

Let us also clear the log file so that it contains only the latest errors. But we cannot afford to lose important logs. So we need to first make a copy of the current log file:

[root@vbg ~]# cat /var/log/audit/audit.log > /var/log/audit/my-audit-log-19Dec09

Now, let us empty the log file:

[root@vbg ~]# >/var/log/audit/audit.log

…and repeat the chcon command:

[root@vbg ~]# chcon -t lfy_t /var/www/html/index.html

Let us have a look at AVC denial messages in the new log file:

[root@vbg ~]# cat /var/log/audit/audit.log | grep -i deni
type=AVC msg=audit(1261195413.081:42): avc:  denied  { relabelto } for  pid=2328 comm="chcon" name="index.html" dev=sda2 ino=104970 scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 tcontext=system_u:object_r:lfy_t:s0 tclass=file
type=AVC msg=audit(1261195413.081:42): avc:  denied  { associate } for  pid=2328 comm="chcon" name="index.html" dev=sda2 ino=104970 scontext=system_u:object_r:lfy_t:s0 tcontext=system_u:object_r:fs_t:s0 tclass=filesystem

We can see that two actions are disallowed. Let us write the allow rules for them:

allow unconfined_t lfy_t : file { relabelto }
allow lfy_t fs_t : filesystem { associate }

Let us update our module policy file, test.te:

[vbg@vbg test-selinux]$ vim test.te
policy_module(test, 1.1)

type lfy_t;

allow unconfined_t lfy_t : file { relabelto };
allow lfy_t fs_t : filesystem { associate };

Save and close. (Do note that we have now increased the version number to 1.1.)

Compile the test.te source file by running the make command:

[vbg@vbg test-selinux]$ make test.pp
Compiling targeted test module
/usr/bin/checkmodule:  loading policy configuration from tmp/test.tmp
test.te":5:ERROR 'unknown type unconfined_t' at token ';' on line 3199:

allow unconfined_t lfy_t : file { relabelto };
/usr/bin/checkmodule:  error(s) encountered while parsing configuration
make: *** [tmp/test.mod] Error 1

Oops! We have received an error while compiling our module!

This is because we have not defined the types and classes used elsewhere in our source file (test.te). But are these types not already defined in the policy? Doesn’t unconfined_t exist already?

It does, but we need to explicitly define which types and classes are required for our module. To solve this error, let us define the types in the required section of our source file. We explicitly add the following lines to our source:

require {
        type unconfined_t;
        type fs_t;
}

So that the new test.te is:

[vbg@vbg test-selinux]$ cat test.te
policy_module(test, 1.1)

require {
	type unconfined_t;
	type fs_t;
}

type lfy_t;

allow unconfined_t lfy_t : file { relabelto };
allow lfy_t fs_t : filesystem { associate };

Let us now compile this again:

[vbg@vbg test-selinux]$ make test.pp
Compiling targeted test module
/usr/bin/checkmodule:  loading policy configuration from tmp/test.tmp
/usr/bin/checkmodule:  policy configuration loaded
/usr/bin/checkmodule:  writing binary representation (version 10) to tmp/test.mod
Creating targeted test.pp policy package
rm tmp/test.mod.fc tmp/test.mod

Pages: 1 2

Leave a Reply

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