Bug 1166071

Summary: selinux policy considerations for private and public resolv.conf
Product: [Fedora] Fedora Reporter: Pavel Šimerda (pavlix) <psimerda>
Component: selinux-policyAssignee: Miroslav Grepl <mgrepl>
Status: CLOSED EOL QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: low Docs Contact:
Priority: unspecified    
Version: 22CC: dominick.grift, dwalsh, kchamart, lrintel, lvrabec, mgrepl, plautrba, psimerda, rbarlow, teg, thaller
Target Milestone: ---   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2016-07-19 20:07:07 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1125267    

Description Pavel Šimerda (pavlix) 2014-11-20 11:17:53 UTC
We have plans to turn /etc/resolv.conf (the public resolv.conf) into a symlink to a private resolv.conf in /run/name-of-a-service depending on who's currently the provider of /etc/resolv.conf data. The purpose of this bug is to include selinux in the considerations from the beginning as well as to finally modify the selinux policy to allow for such a change.

Let's look at the following situations:

1) Administrator creates /etc/resolv.conf using a text editor or using the installer.

Works out of the box now.

2) NetworkManager writes its own /run/NetworkManager/resolv.conf and replaces /etc/resolv.conf with a symlink to it.

https://bugzilla.redhat.com/show_bug.cgi?id=1116999

It could be done as follows (please review the consequences for selinux:

 * open("/run/NetworkManager/resolv.conf.tmp", O_WRONLY); write(); close();
 * rename("/run/NetworkManager/resolv.conf.tmp", "/run/NetworkManager/resolv.conf");
 * symlink("/run/NetworkManager/resolv.conf", "/etc/.resolf.conf.NetworkManager");
 * rename("/etc/.resolf.conf.NetworkManager", "/etc/resolv.conf");

This should be allowed.

3) dnssec-trigger writes its own /run/dnssec-trigger/resolv.conf and replaces /etc/resolv.conf with a symlink to it.

https://bugzilla.redhat.com/show_bug.cgi?id=1125267

Same as NetworkManager except dnssec-trigger daemon normally the /etc/resolv.conf with the immutable flag for security reasons which is no longer possible with the symlink. We would like to ensure that dnssec-trigger still has a way to lock /etc/resolv.conf but we don't know whether there's a way with selinux that would work on symlinks.

Without symlinks, this is not hard to achieve:

 * open("/etc/.resolv.conf.dnssec-trigger", O_WRONLY); write(...); close(...);
 * system("chattr -i /etc/resolv.conf");
 * rename("/etc/.resolv.conf.dnssec-trigger", "/etc/resolv.conf");
 * system("chattr +i /etc/resolv.conf");

This is a major concern how to get this working with the symlinks.

4) resolved writes its own private resolv.conf and replaces /etc/resolv.conf with a symlink to it.

Same as NetworkManager.

5) dnssec-trigger wants to give control back to NetworkManager.

 * symlink("/run/NetworkManager/resolv.conf", "/etc/.resolf.conf.dnssec-trigger")
 * rename("/etc/.resolf.conf.dnssec-trigger", "/etc/resolv.conf")

This should be allowed.

6) A tool rewrites /etc/resolv.conf directly when it's a symlink to a private resolv.conf.

/etc/resolv.conf -> /run/dnssec-trigger/resolv.conf

 * open("/etc/resolv.conf", O_WRONLY); write(...); close(...);

This should be blocked by selinux. I'm curious whether we could lock it hard (i.e. to somehow only allow dnssec-trigger and dnssec-trigger-script write there). The same for NetworkManager.

7) A tool not using symlinks replaces /etc/resolv.conf correctly.

 * open("/etc/.resolv.conf.my-tool", O_WRONLY); write(...); close(...);
 * rename("/etc/.resolv.conf.my-tool", "/etc/resolv.conf");

This should be allowed.

8) An administrator is going to use /etc/resolv.conf directly again.

 * When dnssec-trigger is running, this may not be allowed, possibly depending on configuration.
 * After dnssec-trigger is stopped, the symlink no longer point to its private resolv.conf and /etc/resolv.conf is not locked in any way.
 * When NetworkManager is running, administrator often wants to temporarily replace the /etc/resolv.conf. When he's done with experiments, he could install the symlink manually again.
 * After NetworkManager is stopped, it should ensure there's no longer a symlink to its private copy and that /etc/resolv.conf is directly editable as usual.

When /etc/resolv.conf is still a symlink and it's not locked from being changed, the administrator has to do the following:

 * rm /etc/resolv.conf
 * vim /etc/resolv.conf

When it's cleaned up so that there's no longer a symlink, the second command should be good enough.

Comment 1 Daniel Walsh 2014-11-20 12:31:25 UTC
This seems awfully fragile.

Not crazy about constantly changing the /etc/resolv.conf.  

Just as a crazy thought, has anyone thought about using bind mounts instead of symbolic links?


mount -o bind /run/NetworkManager/resolv.conf /etc/resolv.conf
...

umount /etc/resolv.config

mount -o bind /run/dnssec/resolv.conf /etc/resolv.conf

Comment 2 Petr Lautrbach 2014-11-20 14:37:56 UTC
> 6) A tool rewrites /etc/resolv.conf directly when it's a symlink to a private resolv.conf.
...
> This should be blocked by selinux. I'm curious whether we could lock it hard (i.e. to somehow only allow dnssec-trigger and dnssec-trigger-script write there). The same for NetworkManager.

What would you do if SELinux is in permissive mode or even disabled?

Comment 3 Miroslav Grepl 2014-11-20 14:42:21 UTC
At least 6) point won't work from SELinux point of view. If your tool runs as unconfined, you are not restricted. Also some domains can use *_run_t private types together.

Comment 4 Pavel Šimerda (pavlix) 2014-12-02 08:37:20 UTC
(In reply to Miroslav Grepl from comment #3)
> At least 6) point won't work from SELinux point of view. If your tool runs
> as unconfined, you are not restricted. Also some domains can use *_run_t
> private types together.

Thanks. I understand that an unconfined root can do just anything and we can only hope that interactive unconfined tools would warn (because of write permissions missing) and uninteractive ones would be used by someone who knows what he's doing.

(In reply to Petr Lautrbach from comment #2)
> What would you do if SELinux is in permissive mode or even disabled?

Rely on the good behavior of applications, which, by the way, would be tested in enforcing mode. Talking about the confined apps only, due to the information above.

So we have basically two options:

1) To accept that symlinks cannot be guarded using the immutable bit, rely on good behavior of applications, enforce it using selinux (when applicable) and trust the administrator. I'm happily using this option on my local machine but somehow I sense not everyone will be happy with that :).

2) To step back and only use symlinks for all software except dnssec-trigger. Make dnssec-trigger a notable exception that creates resolv.conf as a regular file and guards it using the immutable bit as before. The immutable bit has the advantage that it must be explicitly unset before one can remove or modify the file.

Comment 5 Pavel Šimerda (pavlix) 2015-01-21 13:25:46 UTC
(In reply to Pavel Šimerda (pavlix) from comment #4)
> 2) To step back and only use symlinks for all software except
> dnssec-trigger. Make dnssec-trigger a notable exception that creates
> resolv.conf as a regular file and guards it using the immutable bit as
> before. The immutable bit has the advantage that it must be explicitly unset
> before one can remove or modify the file.

Sticking with this approach for now but open to any new information.

Comment 6 Jaroslav Reznik 2015-03-03 16:31:38 UTC
This bug appears to have been reported against 'rawhide' during the Fedora 22 development cycle.
Changing version to '22'.

More information and reason for this action is here:
https://fedoraproject.org/wiki/Fedora_Program_Management/HouseKeeping/Fedora22

Comment 7 Randy Barlow 2016-03-15 20:45:06 UTC
I have noticed that Pulp is not allowed to read /etc/resolv.conf in my testing on Fedora Rawhide. audit2allow suggests allowing net_conf_t:lnk_file read. I tried to use the sysnet_dns_name_resolve() reference policy, but that only grants net_conf_t:file read. I think that adding this line to sysnet_read_config() in the policy may fix the problem:

allow $1 net_conf_t:lnk_file read_file_perms;

Pulp needs this for Rawhide. If Fedora 24 also has resolv.conf as a symlink, we will need this there as well.

Comment 8 Randy Barlow 2016-03-15 21:01:49 UTC
I have submitted a pull request with the suggestion I made above:

https://github.com/fedora-selinux/selinux-policy/pull/110

Comment 9 Randy Barlow 2016-03-16 19:19:03 UTC
This does affect Fedora 24, so I'm marking the bug there.

I've had some back-and-forth on my pull request, and we are puzzled why the statement inside the ifdef(`distro_redhat'… section's statement does not solve this net_conf_t:lnk_file denial.

Is the mixture of tabs and spaces a problem perhaps?

Comment 10 Randy Barlow 2016-03-16 21:13:20 UTC
I am suspicious of a problem in this block:

https://github.com/fedora-selinux/selinux-policy/blob/0e33fe3a94da8f8ce78cd10dd395d7c0821147d8/policy/modules/system/sysnetwork.if#L452-L458

grift and I chatted on IRC about this, and it seems that the first line of that block (files_search_all_pids($1)) is getting applied on my system, but the second line (init_search_pid_dirs($1)) is not.

$ sesearch -A -ds celery_t -t pidfile
Found 1 semantic av rules:
   allow celery_t pidfile : dir { getattr search open } ;

$ sesearch -A -ds celery_t -t init_var_run_t

That second command had no output. This shows that sysnet_dns_name_resolve(celery_t) does hit files_search_all_pids(celery_t) but not init_search_pid_dirs(celery_t).

I have not been able to tell what is going on, but I wanted to mention what we learned in greater detail here. For context, this is from me trying to add sysnet_dns_name_resolve(celery_t) to the Pulp pulp-celery policy:

https://github.com/pulp/pulp/blob/f1e07e763a2d61d52204fca642578d4f9bf67578/server/selinux/server/pulp-celery.te

Comment 11 Randy Barlow 2016-03-16 21:49:10 UTC
grift helped me out big time in #selinux and he got me to try using auth_use_nsswitch(celery_t) instead of sysnet_dns_name_resolve(celery_t). This worked for me! I really can't explain why I was experiencing the issues above, but I am convinced that I was either doing something wrong (highly likely, I'm new at SELinux policy writing) or something else weird was happening. Either way, I'm sorry for all the noise and I'm going to reset this bug back to F22 like it was before I added a hundred comments.

Comment 12 Fedora End Of Life 2016-07-19 20:07:07 UTC
Fedora 22 changed to end-of-life (EOL) status on 2016-07-19. Fedora 22 is
no longer maintained, which means that it will not receive any further
security or bug fix updates. As a result we are closing this bug.

If you can reproduce this bug against a currently maintained version of
Fedora please feel free to reopen this bug against that version. If you
are unable to reopen this bug, please file a new report against the
current release. If you experience problems, please add a comment to this
bug.

Thank you for reporting this bug and we are sorry it could not be fixed.