Bug 6580 - [PATCH] Breaks builds when running as confined SELinux user
Summary: [PATCH] Breaks builds when running as confined SELinux user
Status: NEW
Alias: None
Product: Pseudo
Classification: Yocto Project Subprojects
Component: pseudo (show other bugs)
Version: unspecified
Hardware: x86 Multiple
: Medium normal
Target Milestone: 6.99
Assignee: Unassigned
QA Contact:
URL:
Whiteboard:
: 6581 (view as bug list)
Depends on:
Blocks: 6581
  Show dependency tree
 
Reported: 2014-07-26 11:25 UTC by Enrico Scholz
Modified: 2026-06-19 13:04 UTC (History)
7 users (show)

See Also:
OS type for building Yocto: ---
Type of Regression: ---
Verified:
Documentation change: No (bug/feature does not impact docs)


Attachments
disables SELinux for wrapped applications. (5.42 KB, patch)
2014-07-26 16:16 UTC, Enrico Scholz
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Enrico Scholz 2014-07-26 11:25:09 UTC
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
Comment 1 Enrico Scholz 2014-07-26 16:16:12 UTC
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.
Comment 2 Mark Hatle 2014-07-28 14:08:33 UTC
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.)
Comment 3 Enrico Scholz 2014-07-28 14:37:52 UTC
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.
Comment 4 Mark Hatle 2014-07-28 15:51:34 UTC
(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.
Comment 5 Enrico Scholz 2014-07-28 16:51:04 UTC
> 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.
Comment 6 Enrico Scholz 2014-07-28 17:04:51 UTC
fyi: I posted to the maillist

http://article.gmane.org/gmane.comp.handhelds.openembedded.core/53815
Comment 7 Seebs 2015-01-09 17:15:37 UTC
*** Bug 6581 has been marked as a duplicate of this bug. ***
Comment 8 Seebs 2015-01-09 17:19:56 UTC
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.
Comment 9 Seebs 2018-03-06 12:52:04 UTC
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".
Comment 10 Stephano Cetola 2018-04-19 14:56:59 UTC
Reassign to "unassigned" and set to "2.99. We can discuss SELinux feature requests for 2.6.
Comment 11 Seebs 2018-04-27 08:57:36 UTC
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.
Comment 12 Randy MacLeod 2024-06-13 15:10:12 UTC
We really should fix this soon, more distro are enabling SE Linux by default (Fedora).
Comment 13 Randy MacLeod 2026-06-18 15:23:26 UTC
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.