SELinux File Name Transition
This change allows us to write a rule in policy that states if a process labelled A_t creates a specified object class in a directory labelled B_t and the specified object class is named "objectname", it will get the label C_t.
An example of this would be the administrator going into the /root directory and creating the .ssh directory. In previous versions of Fedora, the directory would get created admin_home_t, even though the policy requires it to be labelled ssh_home_t.
Now we can write a rule in policy that states, if the unconfined_t process creates the ".ssh" directory in a directory labelled admin_home_t, then it will get created with the label ssh_home_t.
- Name: Daniel J Walsh
- Email: firstname.lastname@example.org
- Targeted release: [Fedora 16]
- Last updated: Friday June 10 2012
- Percentage of completion: 100%
SELinux has always had a problem of how to get the default labels on an object when the object is created. Up until now, their have been three ways of getting the initial label on an object.
The default way an object gets labelled is to inherit the label of the parent directory. If you create a file named foo in a directory labelled etc_t, then foo will be labelled etc_t.
This works well in most cases, but in some cases you want to have multiple files within a directory with different labels.
Policy writers have the ability to overwrite this by writing a rule in policy that states, if a process with type a_t creates a object of class "file" in a directory labelled b_t, the object will get created c_t. One problem with this is that you might have a single program that is going to create multiple objects in the same directory where each object requires a separate directory.
Some applications have SELinux awareness in them that allow them to ask the system what the label of a certain path should be and then they request from the kernel that the object be created with this label. Examples of applications with SELinux awareness are obviously rpm, restorecon, and udev. Another less known example of an application with SELinux is the password command. passwd recreates the /etc/passwd and /etc/shadow file. /etc/passwd should be labelled etc_t, and shadow should be labelled shadow_t. Because of this and some other concerns, the passwd command has SELinux awareness built into it, and it asks the kernel to create the /etc/passwd and /etc/shadow file with the correct default label.
But we can not instrument every application that creates a file/directory on the system with SELinux awareness. So a user creating the public_html directory in his home directory using mkdir will create the directory with the label user_home_t instead of the correct httpd_user_content_t. An administrator creating the /etc/resolv.conf with sed will create the file labelled etc_t rather then net_conf_t. Or even the kernel creating /dev/rfcomm0 with the label device_t rather then tty_device_t. In these cases we have either required the user/administrator to run the restorecon command on the newly created object "restorecon ~/public_html", or we have added racy tools like restorecond or udev which watch for the creation of objects using inotify, and then relabel them with the correct label. All three of these end up creating an AVC for a confined domain, if not fixed before a confined domain tries to use the object.
With File Name Transitions Features, policy writers can write rules that take into account the file name, not the file path. This is the basename of the file path. Since the kernel knows at the time of object creation the label of the containing directory, the label of the process creating the object and the objects Name. we can now write a policy rule that states, if an unconfined_t process creates a file named resolv.conf in a directory labelled etc_t, the file should get labelled resolv.conf.
- Examples of policy rule:
- filetrans_pattern(kernel_t, device_t, xserver_misc_device_t, chr_file, "nvidia0")
- filetrans_pattern(puppet_t, etc_t, krb5_conf_t, file, "krb5.conf")
We also added various rules, including:
- kernel_t creating a chr_file named rfconmm0 in a directory labelled device_t should create it labelled tty_device_t.
- For Example /dev/rfcomm
- sysadm_t creating a directory named .ssh in a directory labelled admin_home_t should create it labelled ssh_home_t.
- Example: /root/.ssh
- staff_t creating a directory named public_html in a directory labelled user_home_dir_t should create it labelled http_user_content_t.
- For Example /home/dwalsh/public_html
Note: this feature is just about initial file creation. Objects with the wrong label on them will not be magically be fixed with this feature. This feature does not use the path to determine the label, since the path can be variable in the kernel. (Hard/Soft Links, Bind Mounts, Namespacing can all effect the path).
Note 2: The kernel team wants me to point out that this is an exact strcmp match. No regex, no glob, and no hope of that ever changing.
Benefit to Fedora
The major benefit to Fedora is the decrease of SELinux labelling errors, these policy changes will fix a large number of issues SELinux users have with SELinux. Over the years the largest amount of SELinux errors come down to incorrectly labelled files/directories, if we can work to make sure most of them are labelled correctly without the user or admin needing to understand how SELinux works, then the less likely for SELinux to create problems. This feature also has the potential to make the system more secure, because a badly labelled file might give other confined objects the chance to read/write the content. For example most confined applications should not be reading the contents of the .ssh directory, but if it gets the label of the users home directory by default (As it does in current Fedoras), a confined application may be allowed to read the private key file.
This change only effects Policy writers and the kernel. No other applications should be effected by this change.
How To Test
This initial policy work has been done and effects the following directories, /root, $HOME, /dev, /etc.
Things I would like to see checked. First make sure restorecond is not running. killall -9 restorecond.
yum remove policycoreutils-restorecond
- Public_html test.
# useradd test # mkdir /home/test/public_html Verify /home/test/public_html is labelled correctly # restorecon -v /home/test/public_html # No output expected
- Verify all files created when you graphically login are created with the correct label.
Now login graphically to test account. # restorecon -R -v ~/test #Hopefully no output...
- Creating /root/.ssh test
# mv /root/.ssh /root/.ssh.old # mkdir /root/.ssh # restorecon -v /root/.ssh # No output expected # rmdir /root/.ssh # mv /root/.ssh.old /root/.ssh
- Creating /etc/resolv.conf
# mv /etc/resolv.conf /tmp # cp /tmp/resolv.conf /etc # restorecon -v /tmp/resolv.conf # No output expected
- Bluetooth having the kernel create the device with the correct label
Plugin in bluetooth device, no avc about bluetooth_t trying to interact with a device_t chr_file.
- Verify the kernel will create files in the users home directory on the server with the correct label when shared over NFS.
Setup nfs to share a users homedir, mount the homedir on a remote client and create the .public_html directory. Make sure on the server the directory gets created with the correct label.
If you find other objects that could use this feature, open a bugzilla and we can discuss.
It really should not be noticed by the user, unless they are looking for it, although hopefully they will notice that SELinux is working better.