Bug 1667524

Summary: Running authselect in container produces AVC denial
Product: Red Hat Enterprise Linux 8 Reporter: Oleg Kozlov <okozlov>
Component: authselectAssignee: Pavel Březina <pbrezina>
Status: CLOSED CURRENTRELEASE QA Contact: Steeve Goveas <sgoveas>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 8.0CC: jpazdziora, lsm5, lvrabec, okozlov, pbrezina, plautrba, tdudlak
Target Milestone: rcKeywords: Regression
Target Release: 8.0   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2019-02-14 14:49:57 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:

Description Oleg Kozlov 2019-01-18 17:29:27 UTC
Description of problem:

Running `authselect select sssd with-sudo --force` in container based on rhel8 image produces AVC denial on rhel8 host / fedora 29 host system when selinux is in enforcing mode.

Version-Release number of selected component (if applicable):
* container-selinux-2.75-1.git99e2cfd.module+el8+2650+e6b3d617.noarch
* podman-1.0.0-1.git82e8011.module+el8+2696+e59f0461.x86_64
* selinux-policy-3.14.1-51.el8.noarch

Steps to Reproduce:
1. Build image based or rhel8 image with docker or podman with authselect using (e.g. build freeipa-server image based on rhel8 image)
2. Check audit.log for AVC denials.

Actual results:

Error at image building step
```
STEP 52: RUN authselect select sssd with-sudo --force && mv /usr/bin/authselect /usr/bin/authselect.orig
Backup stored at /var/lib/authselect/backups/2019-01-16-14-44-46.gkcHbp
[error] Unable to set fscreate selinux context!
[error] Unable to create temporary file for [/var/lib/authselect/system-auth] [5]: Input/output error
[error] Unable to write temporary file [/var/lib/authselect/system-auth] [5]: Input/output error
[error] Unable to write generated system files [5]: Input/output error
[error] Unable to activate profile [sssd] [5]: Input/output error
free(): double free detected in tcache 2
/bin/sh: line 1:     8 Aborted                 (core dumped) authselect select sssd with-sudo --force
error building at step {Env:[PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin container=oci] Command:run Args:[authselect select sssd with-sudo --force && mv /usr/bin/authselect /usr/bin/authselect.orig] Flags:[] Attrs:map[] Message:RUN authselect select sssd with-sudo --force && mv /usr/bin/authselect /usr/bin/authselect.orig Original:RUN authselect select sssd with-sudo --force && mv /usr/bin/authselect /usr/bin/authselect.orig}: error while running runtime: exit status 134
```

AVC
```
# ausearch -m AVC -te recent
----
time->Thu Jan 17 07:46:09 2019
type=PROCTITLE msg=audit(1547729169.149:867): proctitle=6175746873656C6563740073656C656374007373736400776974682D7375646F002D2D666F726365
type=SYSCALL msg=audit(1547729169.149:867): arch=c000003e syscall=1 success=no exit=-13 a0=3 a1=55ed11082ed0 a2=1f a3=0 items=0 ppid=807 pid=819 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts0 ses=7 comm="authselect" exe="/usr/bin/authselect" subj=system_u:system_r:container_t:s0:c528,c834 key=(null)
type=AVC msg=audit(1547729169.149:867): avc:  denied  { setfscreate } for  pid=819 comm="authselect" scontext=system_u:system_r:container_t:s0:c528,c834 tcontext=system_u:system_r:container_t:s0:c528,c834 tclass=process permissive=0
```

Possible workaround
```
# echo '( allow container_t self ( process ( setfscreate)))' > authselect.cil
# semodule -i authselect.cil
```

authselect.te file generated by `grep authselect /var/log/audit/audit.log | audit2allow -M authselect` command
```

module authselect 1.0;

require {
	type container_t;
	class process setfscreate;
}

#============= container_t ==============
allow container_t self:process setfscreate;
```

Expected results:
No AVC denials.

Comment 2 Pavel Březina 2019-01-21 09:09:59 UTC
I guess this was introduced by fixing [1]. Internally, authselect now calls selinux api to set proper label on generated files (setfscreatecon [2]). Obviously, SELinux is preventing authselect to use this function. Since the fix seems to be change in selinux policy, I'm moving this bug there.

[1] https://bugzilla.redhat.com/show_bug.cgi?id=1664650
[2] https://github.com/pbrezina/authselect/commit/9451dd55c43ce704e520dd4d62676466cc68b71e#diff-4f5513ba0e1cbc67450a675d4d7c228dR118

Comment 3 Pavel Březina 2019-01-23 12:19:14 UTC
I am setting blocker? as this needs to be fixed in rhel 8.0. Since authselect is new tool that is replacing authconfig it would be very inconvenient if it can not be run inside containers and for this not being able to install e.g. ipa server.

Please, fix it in selinux policy if possible or advice me on how to fix this issue in authselect. Thank you.

Comment 5 Pavel Březina 2019-01-23 16:05:53 UTC
Since you see avc denials I expect that the problem in container will be in selinux policy but I have another bug [1] where the same backtrace is caused by having selinux disabled. Do you have selinux enabled?

[1] https://bugzilla.redhat.com/show_bug.cgi?id=1668025

Comment 6 Oleg Kozlov 2019-01-24 09:23:35 UTC
Yes, selinux is enabled (is in enforcing mode). And I wasn't able to reproduce this bug after execution of `setenforce 0` on host system, so I guess it's related to selinux.

Comment 7 Pavel Březina 2019-01-28 12:39:43 UTC
Thank you. This is a different issue then [1]. There is a problem in [1] because authselect tries to obtain default selinux context for a file when selinux is disabled. In this bug, we fail to set default selinux context using setfscreate() because selinux policy does not allow authselect to do it. If there are any steps required in authselect, please advice me. Otherwise I would like you to ask selinux maintainers to fix it in policy.

The consequences of not having it in RHEL 8.0 is that authselect is not functioning inside containers and it will break tools such as ipa-client/server-install or reamld which relies on authselect to configure the system.

[1] https://bugzilla.redhat.com/show_bug.cgi?id=1668025

Comment 8 Jan Pazdziora 2019-02-07 15:14:08 UTC
Why should authselect do anything with SELinux contexts in containers where (from the point of view of processes in the container) SELinux is disabled, and context are managed outside of the container confinement? Doesn't authselect try to do something that it has no business of doing?

Comment 9 Pavel Březina 2019-02-08 09:25:20 UTC
Code-wise, authselect does this:
https://github.com/pbrezina/authselect/commit/9451dd55c43ce704e520dd4d62676466cc68b71e#diff-4f5513ba0e1cbc67450a675d4d7c228dR118

When creating configuration files, e.g. /etc/authselect/nsswitch.conf it:
1) Get default context for /etc/authselect/nsswitch.conf
2) Using setfscreatecon set the context to be used with next created file
3) Create temporary file /etc/authselect/nsswitch.conf.XXXXXX
4) Later it renames it to /etc/authselect/nsswitch.conf

So we set the selinux context for temporary file to match the final destination.

If selinux is disabled, why does it produce avc denial?

Comment 10 Jan Pazdziora 2019-02-08 09:30:53 UTC
Why isn't all this done simply in the policy, rather than in the application code? It seems very error-prone.

SELinux acts as disabled in containers because you cannot do things like relabel in confined environment. But it does not mean that it is not active on the host, where an attempt to set setfscreatecon is caught.

Comment 11 Pavel Březina 2019-02-08 09:52:44 UTC
This was advised upstream: https://github.com/pbrezina/authselect/issues/128

What is the correct solution?

Comment 12 Jan Pazdziora 2019-02-08 10:57:13 UTC
Please talk to the SELinux team (Lukáš V.) for the best solution. If authselect runs in its own SELinux domain, file transition rule should be possible. If it does not run in its own domain, maybe it should. Even if it does not, perhaps filetrans_pattern could be used.

The SELinux team should be consulted.

Comment 13 Pavel Březina 2019-02-08 11:50:32 UTC
Lukáš, can you please advise what the solution should be?

Authselect calls some selinux API to ensure that generated files have proper label, see comment #9. This does not seem to work in container, see the bug description.

Thank you.

Comment 14 Lukas Vrabec 2019-02-11 15:55:20 UTC
Had small talk with Petr Lautrbach, there could be some issue in sssd SELinux part, where maybe miss some check for SELinux state. 

Petr, 
PTAL.

Comment 15 Jan Pazdziora 2019-02-11 16:22:22 UTC
That could be the case ... but could please also comment on the general suitability of authselect code manipulating the SELinux contexts, instead of letting the SELinux policy do it?

Comment 16 Petr Lautrbach 2019-02-11 16:59:22 UTC
I'm looking into this but it looks like authselect doesn't check whether SELinux is enabled before it tries to manipulate SELinux related process attributes:

-    fd = mkstemp(tmpfile);;
-    if (fd == -1) {
-        ret = errno;
+    ret = selinux_mkstemp_of(filepath, &tmpfile);
+    if (ret != EOK) {
+        ERROR("Unable to create temporary file for [%s] [%d]: %s",
+              filepath, ret, strerror(ret));

The fix could be to use is_selinux_enabled() and based on result use mkstemp or selinux_mkstemp_of(), something like:

if (is_selinux_enabled() == 1) 
  ret = selinux_mkstemp_of(filepath, &tmpfile);
else
  ret = mkstemp_of(filepath, &tmpfile);

Comment 17 Petr Lautrbach 2019-02-11 17:02:37 UTC
The same problem appears on a system with SELinux disabled:

[root@rhel-8-nightly ~]# sestatus 
SELinux status:                 disabled

[root@rhel-8-nightly ~]# authselect select sssd with-sudo --force
Backup stored at /var/lib/authselect/backups/2019-02-11-17-02-04.7bIHyp
[error] Unable to get current fscreate selinux context!
[error] Unable to create temporary file for [/var/lib/authselect/system-auth] [5]: Input/output error
[error] Unable to write temporary file [/var/lib/authselect/system-auth] [5]: Input/output error
[error] Unable to write generated system files [5]: Input/output error
[error] Unable to activate profile [sssd] [5]: Input/output error
Unable to activate profile [5]: Input/output error

Comment 18 Petr Lautrbach 2019-02-11 17:17:47 UTC
As for the AVC denial message, the setfscreate() is not necessary inside a container and it has no effect anyway:

[root@fec78fb03e1a /]# python3
Python 3.7.2 (default, Jan  3 2019, 09:14:01) 
[GCC 8.2.1 20181215 (Red Hat 8.2.1-6)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import selinux
>>> selinux.setfscreatecon('system_u:system_r:passwd_t:s0')
0
>>> f = open('/file', 'w')
>>> f.close()
>>> 

[root@fec78fb03e1a /]# attr -S -g selinux /file
Attribute "selinux" had a 30 byte value for /file:
system_u:object_r:fusefs_t:s0


Everything inside the container runs with system_u:system_r:container_t:s0 and all internal files seem to be assigned with system_u:object_r:fusefs_t:s0 context.

Comment 19 Jan Pazdziora 2019-02-11 17:37:10 UTC
Thank you for the analysis.

Do you see a possibility of removing all SELinux-related code from authselect, and doing the equivalent (filetranses or similar) in the SELinux policy?

Comment 20 Petr Lautrbach 2019-02-11 19:41:13 UTC
SELinux policy rules can cover only SELinux type, not the whole context; while the referenced github issue and patch try to restore/set the user part of context. the code in authselect is wrong. You can use libuser code as an example - https://pagure.io/libuser/blob/master/f/lib/util.c#_696 Notice that there's always is_selinux_enabled() and it uses context from the original file instead of the default context.

Comment 21 Pavel Březina 2019-02-12 08:46:08 UTC
The destination file does not yet exist, we are creating it so there is no original file. Therefore it obtains default context for the destination file. I used is_selinux_enabled to fix the issue when selinux is disabled, will it fix also this issue in the container?

It was fixed in authselect-1.0-12.

Comment 22 Pavel Březina 2019-02-12 08:49:43 UTC
Actually to be more precise the file may or may not exist so it should detect if it should use fgetfilecon or obtain the default context.

Oleg, can you please retest this with latest authselect-1.0-12 to se if using is_selinux_disabled() fixed this issue as well? Thank you.

Comment 23 Oleg Kozlov 2019-02-14 14:11:30 UTC
(In reply to Pavel Březina from comment #22)
> Actually to be more precise the file may or may not exist so it should
> detect if it should use fgetfilecon or obtain the default context.
> 
> Oleg, can you please retest this with latest authselect-1.0-12 to se if
> using is_selinux_disabled() fixed this issue as well? Thank you.
Works fine now with updated version. Workaround for image building is not need more. Tested with RHEL8 host + RHEL image. Thanks! 

# rpm -qa | grep authselect
authselect-1.0-12.el8.x86_64
authselect-compat-1.0-12.el8.x86_64
authselect-libs-1.0-12.el8.x86_64
# rpm -qa container-selinux
container-selinux-2.75-1.git99e2cfd.module+el8+2769+577ad176.noarch
# rpm -q podman
podman-1.0.0-2.git921f98f.module+el8+2784+9a0c1dfe.x86_64
# getenforce 
Enforcing

Comment 24 Pavel Březina 2019-02-14 14:49:57 UTC
Thank you Oleg. I am closing this bug as current release.

I created upstream ticket to address Petr's concerns and do it for next release:
https://github.com/pbrezina/authselect/issues/136