| Summary: | [PATCH] Breaks builds when running as confined SELinux user | ||||||
|---|---|---|---|---|---|---|---|
| Product: | [Yocto Project Subprojects] Pseudo | Reporter: | Enrico Scholz <enrico.scholz> | ||||
| Component: | pseudo | Assignee: | Unassigned <unassigned> | ||||
| Status: | NEW --- | QA Contact: | |||||
| Severity: | normal | ||||||
| Priority: | Medium | CC: | ccasciato, randy.macleod, seebs, sgw, stephano, yp.pseudo.watcher, yp.watcher | ||||
| Version: | unspecified | ||||||
| Target Milestone: | 6.99 | ||||||
| Hardware: | x86 | ||||||
| OS: | Multiple | ||||||
| Whiteboard: | |||||||
| OS type for building Yocto: | --- | Type of Regression: | --- | ||||
| Verified: | Documentation change: | No (bug/feature does not impact docs) | |||||
| Bug Depends on: | |||||||
| Bug Blocks: | 6581 | ||||||
| Attachments: |
|
||||||
Created attachment 2059 [details]
disables SELinux for wrapped applications.
I think I found a better solution: disable SELinux for 'pseudo' wrapped applications. I do not see much sense when 'install' sets file contexts defined by the host policy and emulating SELinux requires a lot of work.
Avoiding the lookup in the SELinux policy should speedup builds a little bit too.
In the past the documentation and notes indicated that GRSec and SE Linux were not compatible with pseudo. Both of them can block the LD_PRELOAD requires by pseudo, and in addition 'pseudo's capturing of root-like commands can interfere with the existing system security practices (as you've noticed). We debated if we should just capture the attributes or try to pass them through to the system. The use cases that we have with xattrs are trying to set various security contexts during rootfs image creation, as well as potentially other steps during the build. If we pass these to the system (and they are successfully applied) that the security contexts on the disk could render each of these files unreadable -- or worse, open a security hole in the system. I'd suggest brining this up on the oe-core mailing list, if it hasn't already been. And we need to discuss this on an open forum to try to come up with a solution. Until then the only alternative is to disable SE Linux. (That has been the suggestion since YP 0.9.) Confined and unconfined SELinux worked with pseudo < 1.6. But pseudo 1.6+ breaks it unfixable (at least, I do not know how to fix it without patching pseudo). > The use cases that we have with xattrs are trying to set various security > contexts during rootfs image creation This is a valid case and can be solved by setting PSEUDO_ALLOW_SELINUX in my patch. But this requires other changes too (e.g. taking SELinux's file_context from the rootfs but not from the host system) which are not done yet. > as well as potentially other steps during the build Which potential steps are you seeing? IMO, install's behavior to set SELinux file context makes sense for 'sudo make install' but is fundamentally broken for 'make install DESTDIR=...'. For DESTDIR installs, all the explicit labeling should be skipped which is done by my patch. (In reply to comment #3) > Confined and unconfined SELinux worked with pseudo < 1.6. Confined was never expected to work, if it did that was lucky, but not verified or engineered into the solution. The issue really is, which security contexts do we capture -- and which ones do we pass through the system. I'm not sure this is something we can even guess at. > But pseudo 1.6+ breaks it unfixable (at least, I do not know how to fix it > without patching pseudo). > > > > The use cases that we have with xattrs are trying to set various security > > contexts during rootfs image creation > > This is a valid case and can be solved by setting PSEUDO_ALLOW_SELINUX in my > patch. But this requires other changes too (e.g. taking SELinux's > file_context from the rootfs but not from the host system) which are not > done yet. I don't see what the patch actually does to 'disable' selinux for wrapped applications? I was unaware of a universal 'selinux' enabled or disabled API. The two functions that are being overridden, where are they defined, in what library. If we are simply overriding functions within an application, this isn't safe to do as different compiler optimizations can avoid the external calls that LD_PRELOAD allows to be overridden. If it's loading the functions from an external library -- then we might have the ability to safely override and tell the system everything is disabled. But why would telling the applications that selinux is disabled on the system cause the system to start working? This is confusing to me as the underlying system and filesystem behavior should be the same via the xattr calls. If pseudo intercepts the call and prevents it from going to the disk, it's the same (to the system) as the call never being made in the first place. > > as well as potentially other steps during the build > > Which potential steps are you seeing? IMO, install's behavior to set > SELinux file context makes sense for 'sudo make install' but is > fundamentally broken for 'make install DESTDIR=...'. For DESTDIR installs, > all the explicit labeling should be skipped which is done by my patch. We've have inquiries from people trying to set security contexts in the do_install step, and then package those contexts up during do_package for later feeding into custom changes to the packaging backends. So the security contexts can be set at any time pseudo is enabled, do_install, do_package, through the do_rootfs stages. > Confined was never expected to work It works... > I don't see what the patch actually does to 'disable' selinux for wrapped > applications? Every SELinux aware application should call 'is_selinux_enabled()' (defined in libselinux) before doing any other SELinux stuff. When 'is_selinux_enabled()' returns false, it should continue as SELinux is disabled. For 'install' this means to avoid calls to selinux_lsetfilecon_default() -> setlxattr(). Other (security sensitive) applications (sshd) might be configured to refuse to start, but I really do not see a sense in doing such things in do_install(). > I was unaware of a universal 'selinux' enabled or disabled API. Unfortunately, there is no way to override 'is_selinux_enabled()' more natively. It uses very low level functions to check existence of directories/files. I tried to forbid access to /sys/fs/selinux by the local SELinux policy but there are rules in the core policy taking precedence. Overriding 'is_selinux_enabled()' by LD_PRELOAD is as clean as the rest of 'pseudo'.... > But why would telling the applications that selinux is disabled on the system > cause the system to start working? Because SELinux API uses more then 'xattr' calls. E.g. for creating files with an explicit label you can do | fd = open("dst", O_CREAT); | lsetxattr("dst", "security.selinux", "system_u:object_r:xdm_tmp_t:s0") or | echo 'system_u:object_r:xdm_tmp_t:s0' > /proc/self/attr/fscreate | open("dst", O_CREAT); First is catched by 'pseudo'. But 'sed -i' uses the second way and 'pseudo' will not recognize the new SELinux label at all. > We've have inquiries from people trying to set security contexts in the > do_install step This is a really bad idea because when relying on the security being set in do_install(), you have to make sure that *every* do_install() generates correct file contexts. This means, you would have to write a local, system wide policy like | /my/local/oe/tmp/path/work/.*/usr/sbin/sudo -- ..., sudo_exec_t, ... Labeling files in the tmp path is insecure and breaks when path changes. Fixing labels at do_rootfs() time would be a much better way and here you can call a chroot aware 'restorecon' with PSEUDO_ALLOW_SELINUX. fyi: I posted to the maillist http://article.gmane.org/gmane.comp.handhelds.openembedded.core/53815 *** Bug 6581 has been marked as a duplicate of this bug. *** So I'm still thinking about this one. The underlying issue is that we don't want pseudo to pick up host system selinux attributes, and indeed, we almost certainly want it to hide them. If pseudo just ignores xattrs entirely, things may well work. If pseudo supports xattrs, though, it has to carefully filter out and ignore any host system xattr values, or it'll result in host contamination. And if pseudo is filtering security-related attributes out, some host stuff won't work correctly any more. Solving this properly is surprisingly difficult. For the mean time, I think the answer may be to make it easier to disable pseudo's xattr support, and suggest that if you need to run in an selinux environment, you should disable pseudo's xattr support, and if you really need to make rootfs images which contain extended attributes, for now, the host will need to be not using selinux. A proper fix is hard to even define, let alone implement. Do we actually want to try to define what a fix for this would look like? If so, I'm not actually at all sure how to do it -- it's not obvious that we really can make this work, because we'd need to somehow distinguish between "virtual environment would like to make virtual environment selinux annotations" and "real host environment would like to make real host environment selinux annotations". Reassign to "unassigned" and set to "2.99. We can discuss SELinux feature requests for 2.6. Oh, that makes sense, we don't actually explicitly shut pseudo down, I think, it just stops when there's no activity for a while. Actually, this gives me an idea for a thing I would like to test, which is whether the problem goes away if we don't disable pseudo. My *suspicion* being that we could be seeing something caused by things happening outside of the pseudo environment but which affect files it was tracking. We really should fix this soon, more distro are enabling SE Linux by default (Fedora). Can we at least detect is we're in an SE Linux environment in sanity and issue an error. We may want to document that it's not a supported enviroment. |
When doing the build as an confined SELinux user, pseudo 1.6.1 in oe master breaks e.g. packages which are executing 'sed -i' in the wrapped do_install(). There is done: $ install src dst $ sed -i -e 's!x!y' dst 1. a previous 'install' sets a SELinux context on 'dst' which would be rejected without pseudo and which would result into a warning. With pseudo, context is recorded as part of xattr handling 2. 'sed -i' asks for the context of 'dst' and sets its own fcontext by writing it into /proc/self/.../fscreate. With 'pseudo' the forbidden context will be told. 3. 'sed -i' tries to 'open(..., O_CREAT)' a temporary file which gets rejected by SELinux policy There is no way to fix this by a local SELinux rule because basic constraints are violated which can be changed in the core policy only. The correct fix is probebly to emulation of SELinux behavior (catching writing into '/proc/self/.../fscreate'). But this might be a bottomless pit. Perhaps, not handling 'security.selinux' xattrs would be a more simple short time solution. The problem is easily reproducible e.g. in Fedora 20: 1. configure system so that some users are confined. E.g. add | __default__:user_u:s0 | %wheel:unconfined_u:s0-s0:c0.c1023 to /etc/selinux/targeted/seusers 2. login as such an user; 'id -Z' should tell something like | $ id -Z | user_u:user_r:user_t:s0 3. go into '/tmp/.ICE-unix/' | cd /tmp/.ICE-unix This directory should exist on every system where X11 is running and SELinux assigns a context of | /tmp/\.ICE-unix(/.*)? system_u:object_r:xdm_tmp_t:s0 4. setup pseudo environment | export PSEUDO_PREFIX=... | export PSEUDO_LIB=... | export PSEUDO_LOCALSTATEDIR=... 5. generate dummy src file | $ echo bad > src 6. execute without 'pseudo' | $ install src dst ; echo $? | install: warning: dst: failed to change context to system_u:object_r:xdm_tmp_t:s0: Permission denied | 0 | $ sed -i 's!bad!good!' dst ; echo $? | 0 | $ cat dst | good 7. execute with 'pseudo' | $ pseudo install src dst ; echo $? | 0 | $ pseudo sed -i 's!bad!good!' dst ; echo $? | sed: couldn't open temporary file ./sedfKIhXT: Permission denied | 4 | $ cat dst | bad The interesting syscalls in stage 6 are: - 'install' | lsetxattr("dst", "security.selinux", "system_u:object_r:xdm_tmp_t:s0", 31, 0) = -1 EACCES (Permission denied) - 'sed' | getxattr("dst", "security.selinux", "user_u:object_r:xdm_tmp_t:s0", 255) = 29 | ... | open("/proc/self/task/21812/attr/fscreate", O_RDWR|O_CLOEXEC) = 4 | write(4, "user_u:object_r:xdm_tmp_t:s0\0", 29) = 29 | ... | open("./sedfciUiG", O_RDWR|O_CREAT|O_EXCL, 0600) = 4 In stage 7, the 'lsetxattr' is not executed but the attributes are recorded by 'pseudo'. The following 'sed' gets the result of 'getxattr()' from pseudo and tries to execute | open("/proc/self/task/21559/attr/fscreate", O_RDWR|O_CLOEXEC) = 4 | write(4, "system_u:object_r:xdm_tmp_t:s0\0", 31) = 31 | ... | open("./sed64e33F", O_RDWR|O_CREAT|O_EXCL, 0600) = -1 EACCES (Permission denied) For completeness, 'install' and 'sed' are generating the following SELinux AVCs | avc: denied { relabelfrom } for pid=7191 comm="install" name="dst" dev="tmpfs" ino=8629881 scontext=user_u:user_r:user_t:s0 tcontext=user_u:object_r:xdm_tmp_t:s0 tclass=file | avc: denied { create } for pid=21559 comm="sed" name="sed64e33F" scontext=user_u:user_r:user_t:s0 tcontext=system_u:object_r:xdm_tmp_t:s0 tclass=file 'audit2allow' on them reports | #!!!! This avc is a constraint violation. You would need to modify | #the attributes of either the source or target types to allow this | #access. | #Constraint rule: | constrain file { create relabelfrom relabelto } ((u1 eq u2 -Fail-) or (t1=user_t eq TYPE_ENTRY -Fail-) { POLICY_SOURCE: can_change_object_identity } ); Constraint DENIED