Hi list, in relocating /etc/libvirt to another filesystem, I encountered another "lnk_file read" permission problem.
First, I setup a selinux equivalence rule between the original path (/etc/libvirtd) and the new one (/tank/kvm/etc/libvirt/).
Original layout/label: [root@whitehole ~]# ls -alZ /etc/ | grep libv drwx------. root root system_u:object_r:virt_etc_t:s0 libvirt
After relocation and context restore (via "chcon -h -t virt_etc_t libvirt"): [root@whitehole ~]# ls -alZ /etc/ | grep libv lrwxrwxrwx. root root system_u:object_r:virt_etc_t:s0 libvirt -> /tank/kvm/etc/libvirt/
After relocation, libvirtd does not start, and audit2allow shows "allow virtd_t virt_etc_t:lnk_file read". Relabeling the link file with "restorecon -F /etc/libvirtd" produces the following output:
[root@gdanti-lenovo etc]# ls -alZ | grep libv lrwxrwxrwx. root root system_u:object_r:etc_t:s0 libvirt -> /tank/kvm/etc/libvirt/
Now libvirtd correctly starts. However, I have some questions: - is this the correct mode to relocate a directory? - this is not the first "lnk_file read" problem I see. Why does the selinux policy prevent this kind of accesses? Do they pose security concerns? Or does the policy simply not expect to deal with relocated daemons? - after "restorecon -F /etc/libvirtd", which causes a relabel with etc_t type, libvirtd correctly starts. Why does the policy enable etc_t link reads, at the same time denying virt_etc_t link reads? - how can I avoid the problem (short of using bind mounts)?
Thanks.
On 05/17/2018 04:44 AM, Gionatan Danti wrote:
Hi list, in relocating /etc/libvirt to another filesystem, I encountered another "lnk_file read" permission problem.
First, I setup a selinux equivalence rule between the original path (/etc/libvirtd) and the new one (/tank/kvm/etc/libvirt/).
Original layout/label: [root@whitehole ~]# ls -alZ /etc/ | grep libv drwx------. root root system_u:object_r:virt_etc_t:s0 libvirt
After relocation and context restore (via "chcon -h -t virt_etc_t libvirt"): [root@whitehole ~]# ls -alZ /etc/ | grep libv lrwxrwxrwx. root root system_u:object_r:virt_etc_t:s0 libvirt -> /tank/kvm/etc/libvirt> After relocation, libvirtd does not start, and audit2allow shows "allow virtd_t virt_etc_t:lnk_file read". Relabeling the link file with "restorecon -F /etc/libvirtd" produces the following output:
[root@gdanti-lenovo etc]# ls -alZ | grep libv lrwxrwxrwx. root root system_u:object_r:etc_t:s0 libvirt -> /tank/kvm/etc/libvirt/
Now libvirtd correctly starts. However, I have some questions:
- is this the correct mode to relocate a directory?
This is one valid way to do it; bind mounts are another. A bind mount would avoid the problem of introducing a new file (the symbolic link) into the pathname lookup and thus avoid a new permission check.
- this is not the first "lnk_file read" problem I see. Why does the selinux policy prevent this kind of accesses? Do they pose security concerns? Or does the policy simply not expect to deal with relocated daemons?
In this case, it is merely the fact that in a stock system, there are no symbolic links with that type and thus no reason to ever have allowed it in the default policy. In general, restricting access to symbolic links is useful in preventing symlink attacks and unauthorized information flow. It appears that this access is allowed in Fedora 27/28.
- after "restorecon -F /etc/libvirtd", which causes a relabel with etc_t type, libvirtd correctly starts. Why does the policy enable etc_t link reads, at the same time denying virt_etc_t link reads?
Likely because there are symlinks under /etc already that are widely accessed and thus that is allowed in the default policy. NB You generally do not want to use chcon, because that context will be overridden upon the next filesystem relabel unless you also add an entry to file_contexts via semanage fcontext. Even in that case, better to add first via semanage fcontext and then run restorecon.
- how can I avoid the problem (short of using bind mounts)?
You can always generate a local policy module using audit2allow to allow the symlinks to be read.
Il 17-05-2018 18:45 Stephen Smalley ha scritto:
This is one valid way to do it; bind mounts are another. A bind mount would avoid the problem of introducing a new file (the symbolic link) into the pathname lookup and thus avoid a new permission check.
Hi Stephen, surely bind mount would avoid the problem, but I find them less "auto-explaining" than an "explict" symlink. But hey - this is a matter of preferences, I suppose.
In this case, it is merely the fact that in a stock system, there are no symbolic links with that type and thus no reason to ever have allowed it in the default policy. In general, restricting access to symbolic links is useful in preventing symlink attacks and unauthorized information flow. It appears that this access is allowed in Fedora 27/28.
Fair enough.
Likely because there are symlinks under /etc already that are widely accessed and thus that is allowed in the default policy.
Sounds good ;)
NB You generally do not want to use chcon, because that context will be overridden upon the next filesystem relabel unless you also add an entry to file_contexts via semanage fcontext. Even in that case, better to add first via semanage fcontext and then run restorecon.
Sure, my chcon was issue with the broken premise that "restorecon -F /etc/libvirtd" would label the symlink the same as original directory - with virt_etc_t. Instead, restorecon, well, restored the correct "etc_t" context for the symlink.
You can always generate a local policy module using audit2allow to allow the symlinks to be read.
True, but the are somewhat difficult to handle. Specifically: - if I lose the template file from which the policy was compiled, adding further permissions to the same policy is inconvenient; - each added policy should have a specific, non overlapping name (right?) - and this means tracing each added policy.
So, each time it is possible, I really try hard to stick with default policy, booleans and fcontext changes. I am missing something that can ease me with creating/managing custom policies? Thanks.
On 05/17/2018 05:03 PM, Gionatan Danti wrote:
Il 17-05-2018 18:45 Stephen Smalley ha scritto:
This is one valid way to do it; bind mounts are another. A bind mount would avoid the problem of introducing a new file (the symbolic link) into the pathname lookup and thus avoid a new permission check.
Hi Stephen, surely bind mount would avoid the problem, but I find them less "auto-explaining" than an "explict" symlink. But hey - this is a matter of preferences, I suppose.
In this case, it is merely the fact that in a stock system, there are no symbolic links with that type and thus no reason to ever have allowed it in the default policy. In general, restricting access to symbolic links is useful in preventing symlink attacks and unauthorized information flow. It appears that this access is allowed in Fedora 27/28.
Fair enough.
Likely because there are symlinks under /etc already that are widely accessed and thus that is allowed in the default policy.
Sounds good ;)
NB You generally do not want to use chcon, because that context will be overridden upon the next filesystem relabel unless you also add an entry to file_contexts via semanage fcontext. Even in that case, better to add first via semanage fcontext and then run restorecon.
Sure, my chcon was issue with the broken premise that "restorecon -F /etc/libvirtd" would label the symlink the same as original directory - with virt_etc_t. Instead, restorecon, well, restored the correct "etc_t" context for the symlink.
You can always generate a local policy module using audit2allow to allow the symlinks to be read.
True, but the are somewhat difficult to handle. Specifically:
- if I lose the template file from which the policy was compiled, adding further permissions to the same policy is inconvenient;
- each added policy should have a specific, non overlapping name (right?) - and this means tracing each added policy.
So, each time it is possible, I really try hard to stick with default policy, booleans and fcontext changes. I am missing something that can ease me with creating/managing custom policies? Thanks.
As to your first point, yes, presently you have to separately keep your source .te/.fc files around to make future changes in that form. With a modern selinux userspace however you can extract the CIL version of the policy module via semodule -c -E, edit that, and then re-insert it.
With respect to the second point, yes, the name of each policy module has to be unique, so you do have to be mindful of that. The distros should likely should define some policy module namespacing rules for local policy modules so that you can at least know that you never need to worry about conflicts with distro-provided or third party package policy. And perhaps audit2allow should automatically use such a prefix.
On 18/05/2018 14:56, Stephen Smalley wrote:
As to your first point, yes, presently you have to separately keep your source .te/.fc files around to make future changes in that form. With a modern selinux userspace however you can extract the CIL version of the policy module via semodule -c -E, edit that, and then re-insert it.
Does RHEL 7.5+ qualifies as "modern selinux userspace"?
With respect to the second point, yes, the name of each policy module has to be unique, so you do have to be mindful of that. The distros should likely should define some policy module namespacing rules for local policy modules so that you can at least know that you never need to worry about conflicts with distro-provided or third party package policy. And perhaps audit2allow should automatically use such a prefix.
Can you point me to any documentation regarding distro-specific policy roule naming?
Thanks you for your very valuable informations!
On 05/18/2018 10:37 AM, Gionatan Danti wrote:
On 18/05/2018 14:56, Stephen Smalley wrote:
As to your first point, yes, presently you have to separately keep your source .te/.fc files around to make future changes in that form. With a modern selinux userspace however you can extract the CIL version of the policy module via semodule -c -E, edit that, and then re-insert it.
Does RHEL 7.5+ qualifies as "modern selinux userspace"?
Seems to work for me even on 7.4 (and perhaps as early as 7.3), semodule -cE <name-of-module> vi <name-of-module>.cil
With respect to the second point, yes, the name of each policy module has to be unique, so you do have to be mindful of that. The distros should likely should define some policy module namespacing rules for local policy modules so that you can at least know that you never need to worry about conflicts with distro-provided or third party package policy. And perhaps audit2allow should automatically use such a prefix.
Can you point me to any documentation regarding distro-specific policy roule naming?
I don't know if there is presently any such guidance or conventions yet. I think Fedora has been working on some policy packaging guidance, but I don't know if they specified a naming convention.
Thanks you for your very valuable informations!
selinux@lists.fedoraproject.org