Note: This is a public test instance of Red Hat Bugzilla. The data contained within is a snapshot of the live data so any changes you make will not be reflected in the production Bugzilla. Email is disabled so feel free to test any aspect of the site that you want. File any problems you find or give feedback at bugzilla.redhat.com.
Bug 1008580 - sshd_net_t should not be hard coded into the application.
Summary: sshd_net_t should not be hard coded into the application.
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Fedora
Classification: Fedora
Component: openssh
Version: rawhide
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Petr Lautrbach
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks: 1152596
TreeView+ depends on / blocked
 
Reported: 2013-09-16 16:06 UTC by Dominick Grift
Modified: 2015-03-11 14:08 UTC (History)
10 users (show)

Fixed In Version: openssh-6.6.1p1-7.fc21
Doc Type: Bug Fix
Doc Text:
Clone Of:
: 1152596 (view as bug list)
Environment:
Last Closed: 2014-11-14 12:10:12 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)
use privsep_preauth context from selinux-policy (3.18 KB, patch)
2014-10-13 15:52 UTC, Petr Lautrbach
no flags Details | Diff

Description Dominick Grift 2013-09-16 16:06:37 UTC
Description of problem:
sshd unable to determine valid context. Probably due to misuse of libselinux ( but do not shoot me if it isnt)

Sep 16 17:51:02 localhost sshd[982]: ssh_selinux_change_context: setcon base_u:base_r:sshd_net_t from base_u:base_r:base_t failed with Invalid argument [preauth]
Sep 16 17:51:05 localhost sshd[982]: Accepted password for root from 192.168.122.1 port 55436 ssh2
Sep 16 17:51:05 localhost sshd[982]: pam_selinux(sshd:session): Open Session
Sep 16 17:51:05 localhost sshd[982]: pam_selinux(sshd:session): Open Session
Sep 16 17:51:05 localhost sshd[982]: pam_selinux(sshd:session): Username= root SELinux User= base_u Level= (null)
Sep 16 17:51:05 localhost sshd[982]: pam_selinux(sshd:session): Unable to get valid context for root
Sep 16 17:51:05 localhost sshd[982]: pam_unix(sshd:session): session opened for user root by (uid=0)
Sep 16 17:51:05 localhost sshd[982]: error: ssh_selinux_setup_pty: security_compute_relabel: Invalid argument

Version-Release number of selected component (if applicable):
openssh-clients-6.2p2-5.fc19.x86_64
openssh-6.2p2-5.fc19.x86_64
openssh-server-6.2p2-5.fc19.x86_64

Comment 1 Daniel Walsh 2013-09-16 19:13:38 UTC
sshd_net_t should not be hard coded into the app.  We need to use a context file which a policy writer would provide and sshd could read to get the proper context.

Comment 2 Miroslav Grepl 2013-09-17 08:41:22 UTC
Dominick,
how did you start sshd? I believe you ran it directly.

# ps -eZ |grep sshd

and re-test.

Comment 3 Dominick Grift 2013-09-17 08:52:48 UTC
Miroslav, believe you me, this bug was triaged. sshd_net_t is hard coded. Hard coding identifiers is bad practice as i have explained almost a year ago here:

http://bachradsusi.livejournal.com/2239.html?thread=447#t447

Comment 4 Miroslav Grepl 2013-09-17 10:59:03 UTC
Yes, I don't tell hard coding is OK.

Comment 5 Dominick Grift 2013-09-17 11:13:19 UTC
I know, but that is the reason for this bugzilla (hard coded types), it wouldnt matter how i ran SSHD.

Comment 6 Miroslav Grepl 2013-09-17 11:36:39 UTC
We want to have sshd which changes the process label and it is allowed only if it runs with the correct labeling. Of course, it should not be done by hard coding.

# grep -r sshd_net openssh-6.2p2
openssh-6.2p2/sshd.c:	ssh_selinux_change_context("sshd_net_t");
openssh-6.2p2/sshd.c.gsskex:	ssh_selinux_change_context("sshd_net_t");
openssh-6.2p2/sshd.c.log-usepam-no:	ssh_selinux_change_context("sshd_net_t");
openssh-6.2p2/sshd.c.vendor:	ssh_selinux_change_context("sshd_net_t");
openssh-6.2p2/sshd.c.fips:	ssh_selinux_change_context("sshd_net_t");

Comment 7 Dominick Grift 2013-09-17 11:53:57 UTC
This was fixed in:

libselinux-2.1.13-19.fc20.x86_64
libselinux-utils-2.1.13-19.fc20.x86_64
libselinux-python-2.1.13-19.fc20.x86_64

Although you might want to get rid of the verbose output:

Security Context base_u:base_r:base_t Assigned
Key Creation Context base_u:base_r:base_t Assigned



However: Do get rid of the hard-coding issue please

Comment 8 Dominick Grift 2013-09-17 12:00:10 UTC
(In reply to Dominick Grift from comment #7)

> 
> Although you might want to get rid of the verbose output:
> 
> Security Context base_u:base_r:base_t Assigned
> Key Creation Context base_u:base_r:base_t Assigned
> 

Forget the above my pam_selinux was still configured with verbose debug

Comment 9 Dominick Grift 2013-09-17 12:12:21 UTC
(In reply to Miroslav Grepl from comment #6)
> We want to have sshd which changes the process label and it is allowed only
> if it runs with the correct labeling. Of course, it should not be done by
> hard coding.

I don' t really understand that reasoning though (i might just be ignorant). Whether sshd is allowed to change identifiers is defined in security policy.

All it needs to do is determine its current context and then calculate whether its allowed (by security policy) to change to the requested context.

If the policy allows it then: do it, else exit 1

Again, i might be oversimplifying this

Comment 10 Miroslav Grepl 2013-09-17 12:53:59 UTC
(In reply to Dominick Grift from comment #9)
> (In reply to Miroslav Grepl from comment #6)
> > We want to have sshd which changes the process label and it is allowed only
> > if it runs with the correct labeling. Of course, it should not be done by
> > hard coding.
> 
> I don' t really understand that reasoning though (i might just be ignorant).
> Whether sshd is allowed to change identifiers is defined in security policy.
> 

Sure, it is. I'm not saying the opposite.

"dyntransition" if setcon() is used.

Comment 11 Daniel Walsh 2013-09-17 17:37:39 UTC
We just need to add a context file called sshd_context, then add name value pairs for anything sshd wants to do, if nothing is specified the setcon() does not happen, if a policy writer wants to add a context he needs to populate this file.

Comment 12 Dominick Grift 2013-09-17 17:48:16 UTC
Yes, and now i think i know why that is. To prevent that login users end up in domains like mkhomedir_t or whatever.

Comment 13 Dominick Grift 2013-09-17 17:57:21 UTC
(In reply to Dominick Grift from comment #12)
> Yes, and now i think i know why that is. To prevent that login users end up
> in domains like mkhomedir_t or whatever.

Grrr... no that's not it, You probably do this for the setcon() for sshd_t to sshd_net_t

Comment 14 Miroslav Grepl 2013-09-17 19:49:54 UTC
(In reply to Daniel Walsh from comment #11)
> We just need to add a context file called sshd_context, then add name value
> pairs for anything sshd wants to do, if nothing is specified the setcon()
> does not happen, if a policy writer wants to add a context he needs to
> populate this file.

So there should be a check which tells me what the current sshd context is and I know I want to pick up sshd_net_t in the specific part of the code.

So I will have the following pair for example

sshd_net_t <-> sshd_t

Comment 15 Daniel Walsh 2013-09-24 20:03:43 UTC
Yes we could put something like that in default context or have a config file that says..

sshd_net = sshd_net_t

Currently we have for lxc domains.

# more /etc/selinux/targeted/contexts/lxc_contexts 
process = "system_u:system_r:svirt_lxc_net_t:s0"
file = "system_u:object_r:svirt_lxc_file_t:s0"
content = "system_u:object_r:virt_var_lib_t:s0"

Comment 16 Petr Lautrbach 2013-09-25 11:59:06 UTC
Those context files, do they have some common format? I can see several formats used in files in /etc/selinux/targeted/contexts/ 

Is there any API in libselinux which can be used either to get a context file name or better to get a value? Or is it like a project defines it's own format and data and selinux-policy just provides a context file? 

If sshd read the context, should it read it every time before setcon() or is it enough to read it once during an initialization?

Comment 17 Daniel Walsh 2013-09-25 15:00:41 UTC
It is up to the application to define the format, although I now believe that name value pairs are the best format for this.

It should read the file every time or at least stat the file to see if has been updated.  I would doubt it takes long to read it.  Since the policy could have changed.

Libselinux would just return the path to the file.

Comment 18 Daniel Walsh 2013-09-25 15:15:26 UTC
It is up to the application to define the format, although I now believe that name value pairs are the best format for this.

It should read the file every time or at least stat the file to see if has been updated.  I would doubt it takes long to read it.  Since the policy could have changed.

Libselinux would just return the path to the file.

Comment 19 Petr Lautrbach 2014-10-13 15:52:43 UTC
Created attachment 946481 [details]
use privsep_preauth context from selinux-policy

This patch changes how sshd choose an SELinux context for preauth privsep processes. It depends on selinux_openssh_contexts_path() from libselinux-2.2.2-8.

How it works:
- sshd gets the contexts filename path - /etc/selinux/targeted/contexts/openssh_contexts and looks for "privsep_preauth" key
- if it doesn't exist, sshd will use "sshd_net_t"
- if it's empty (privsep_preauth= ), sshd won't change the context
- otherwise, sshd will try to change the context to the read value. However, this operation is not fatal so when setcon() fails, sshd just logs a problem.


You can try it using a copr build [1] and /etc/selinux/targeted/contexts file containing:
privsep_preauth=sshd_net_t

[1] http://copr.fedoraproject.org/coprs/plautrba/openssh_testing/build/52674/

Comment 20 dac.override 2014-10-16 10:01:11 UTC
The above is not sufficient in my view:

1. change the location/name of the sshd selinux config file to for example:
 /etc/selinux/$SELINUXTYPE/contexts/openssh_contexts

2. implement a selinux awereness option in sshd_config that allow one to enable/disable sshd selinux awareness on runtime (example SELINUX=(true|false))

   - if openssh selinux awareness is enabled in sshd config then openssh requires /etc/selinux/$SELINUXTYPE/contexts/openssh_contexts to be present and valid

     if it does not meet the requirements then sshd should refuse to start with a message like for example: file /etc/selinux/$SELINUXTYPE/openssh_contexts not present or invalid

   - if openssh selinux awareness is disabled in sshd config then openssh should not look for /etc/selinux/$SELINUXTYPE/openssh_contexts and should disable all SELinux code

This implementation should also take into account all other existing SELinux related code in open-ssh

In the past some bad SELinux code managed to make it into upstream openssh, this bad SELinux code should, while were at it, also be fixed.

Comment 21 dac.override 2014-10-16 10:30:17 UTC
Actually, and this is up for debate, the file should probably be called something like

/etc/selinux/$SELINUXTYPE/contexts/openssh_privsep_preauth_context

Its content should probably instead be the full security context that openssh should use for "privsep_preauth"

Example of the content of the /etc/selinux/$SELINUXTYPE/contexts/openssh_privsep_context:

system_u:system_r:sshd_net_t:s0

If any other functionality requires customizable selinux security identifiers then each should have their own respective selinux context file using the same conventions

For an example look at the libvirt code and its accompanying /etc/selinux/$SELINUXTYPE/contexts/virtual_domain_context, and virtual_image_context

Comment 22 Miroslav Grepl 2014-10-16 11:13:27 UTC
Actually no. We want to have a pair in these config files.

What we have for libvirt is wrong and we want to change it also.

Comment 23 Petr Lautrbach 2014-10-16 12:28:42 UTC
Thanks for your input, dac.override.

(In reply to dac.override from comment #20)
> The above is not sufficient in my view:
> 
> 1. change the location/name of the sshd selinux config file to for example:
>  /etc/selinux/$SELINUXTYPE/contexts/openssh_contexts

In fact, this is already part the proposed patch. The path is returned by selinux_openssh_contexts_path() from libselinux. It's '/etc/selinux/targeted/contexts/openssh_contexts' by default  but it depends on SELinux policy type. 

> 2. implement a selinux awereness option in sshd_config that allow one to
> enable/disable sshd selinux awareness on runtime (example
> SELINUX=(true|false))

I don't think this is something worth to have. The Fedora openssh works with SELinux contexts in two cases:

1. it changes SELinux context for an unprivileged pre-authentication process which is responsible only for combination via network and gets sshd_net_t type. The type is hardcoded now, but the proposed patch changes it to read the type from the contexts type.
If you wanted to run 'unprivileged pre-authentication process' with 'sshd_t' type, you could set empty privsep_auth= value in the contexts file.

2. it changes SELinux context for an unprivileged post-authentication process which is run with user's credentials and user's type. It allows to have different port-forwarding rules for different user based on their SELinux user type.

I don't see why we should support running "unconfined" sshd. And it would mean that openssh need to aware about SELinux mode - is it enforcing, permissive?

>    - if openssh selinux awareness is enabled in sshd config then openssh
> requires /etc/selinux/$SELINUXTYPE/contexts/openssh_contexts to be present
> and valid
> 
>      if it does not meet the requirements then sshd should refuse to start
> with a message like for example: file
> /etc/selinux/$SELINUXTYPE/openssh_contexts not present or invalid
> 
>    - if openssh selinux awareness is disabled in sshd config then openssh
> should not look for /etc/selinux/$SELINUXTYPE/openssh_contexts and should
> disable all SELinux code
 
It would break sshd even in permissive mode.

> This implementation should also take into account all other existing SELinux
> related code in open-ssh

I'm not sure what you mean here.

Comment 24 dac.override 2014-10-16 12:58:42 UTC
(In reply to Petr Lautrbach from comment #23)

> > 1. change the location/name of the sshd selinux config file to for example:
> >  /etc/selinux/$SELINUXTYPE/contexts/openssh_contexts
> 
> In fact, this is already part the proposed patch. The path is returned by
> selinux_openssh_contexts_path() from libselinux. It's
> '/etc/selinux/targeted/contexts/openssh_contexts' by default  but it depends
> on SELinux policy type. 

Oh, right. I read https://bugzilla.redhat.com/show_bug.cgi?id=1008580#c19 wrong

> 
> > 2. implement a selinux awereness option in sshd_config that allow one to
> > enable/disable sshd selinux awareness on runtime (example
> > SELINUX=(true|false))
> 
> I don't think this is something worth to have. The Fedora openssh works with
> SELinux contexts in two cases:
> 
> 1. it changes SELinux context for an unprivileged pre-authentication process
> which is responsible only for combination via network and gets sshd_net_t
> type. The type is hardcoded now, but the proposed patch changes it to read
> the type from the contexts type.
> If you wanted to run 'unprivileged pre-authentication process' with 'sshd_t'
> type, you could set empty privsep_auth= value in the contexts file.
> 
> 2. it changes SELinux context for an unprivileged post-authentication
> process which is run with user's credentials and user's type. It allows to
> have different port-forwarding rules for different user based on their
> SELinux user type.
> 
> I don't see why we should support running "unconfined" sshd. And it would
> mean that openssh need to aware about SELinux mode - is it enforcing,
> permissive?
> 

Okay, i think it is not optimal. I stated an alternative for the record. It is up to the professionals to make the ultimate decision.

I think that the solution i suggested may provide the best experience, as it provides the end-user to disable OpenSSHd SELinux awareness on runtime altogether.

> >    - if openssh selinux awareness is enabled in sshd config then openssh
> > requires /etc/selinux/$SELINUXTYPE/contexts/openssh_contexts to be present
> > and valid
> > 
> >      if it does not meet the requirements then sshd should refuse to start
> > with a message like for example: file
> > /etc/selinux/$SELINUXTYPE/openssh_contexts not present or invalid
> > 
> >    - if openssh selinux awareness is disabled in sshd config then openssh
> > should not look for /etc/selinux/$SELINUXTYPE/openssh_contexts and should
> > disable all SELinux code
>  
> It would break sshd even in permissive mode.

I fail to see how, but i trust that you know what you are talking about.

I have stated, what i suspect, is an optimal alternative. For your consideration. It is up to you, the professionals, to make the ultimate decision.

I think hardcoding customizable security identifiers for whatever reason, be it fallback/failover or whatever is sub-optimal.
 
> 
> > This implementation should also take into account all other existing SELinux
> > related code in open-ssh
> 
> I'm not sure what you mean here.

Do a "grep -r unconfined_t" in the upstream openssh tree. It should return some. Those are other hardcoded security identifiers that made it upstream by accident.

Comment 25 dac.override 2014-10-18 09:31:32 UTC
Welp, I tested it (against better judgement) and it does not even work

undefined symbol: openssh_selinux_contexts_path (connection refused)

Have you even done some basic testing?

Comment 26 dac.override 2014-10-18 09:49:28 UTC
Screen recording of test procedure on youtube for reference purposes:

https://www.youtube.com/watch?v=a0NhKIcv_6M&feature=youtube_gdata

Comment 27 Petr Lautrbach 2014-10-20 09:15:19 UTC
> It depends on selinux_openssh_contexts_path() from libselinux-2.2.2-8.

It should have been libselinux-2.3-5, I used wrong libselinux changelog entry.

A temporary scratch build with fixed dependency for Rawhide - http://koji.fedoraproject.org/koji/taskinfo?taskID=7913038 

src.rpm - https://plautrba.fedorapeople.org/openssh/testing/openssh-6.6.1p1-5.testing.3.fc22.src.rpm

Comment 28 dac.override 2014-10-20 16:08:57 UTC
Yes this does fix it for me. I would not call the solution elegant but it does deal with the issue

You can close this as far as I am concerned (I am the original OP under a different nick)

Comment 29 Fedora Update System 2014-11-04 19:42:10 UTC
openssh-6.6.1p1-6.fc21 has been submitted as an update for Fedora 21.
https://admin.fedoraproject.org/updates/openssh-6.6.1p1-6.fc21

Comment 30 Miroslav Grepl 2014-11-05 06:58:53 UTC
Lukas,
could you add

'/etc/selinux/targeted/contexts/openssh_contexts'

to selinux-policy?

Comment 31 Fedora Update System 2014-11-05 19:24:34 UTC
Package openssh-6.6.1p1-6.fc21:
* should fix your issue,
* was pushed to the Fedora 21 testing repository,
* should be available at your local mirror within two days.
Update it with:
# su -c 'yum update --enablerepo=updates-testing openssh-6.6.1p1-6.fc21'
as soon as you are able to.
Please go to the following url:
https://admin.fedoraproject.org/updates/FEDORA-2014-14298/openssh-6.6.1p1-6.fc21
then log in and leave karma (feedback).

Comment 32 Fedora Update System 2014-11-10 06:07:59 UTC
Package openssh-6.6.1p1-7.fc21:
* should fix your issue,
* was pushed to the Fedora 21 testing repository,
* should be available at your local mirror within two days.
Update it with:
# su -c 'yum update --enablerepo=updates-testing openssh-6.6.1p1-7.fc21'
as soon as you are able to.
Please go to the following url:
https://admin.fedoraproject.org/updates/FEDORA-2014-14298/openssh-6.6.1p1-7.fc21
then log in and leave karma (feedback).

Comment 33 Fedora Update System 2014-11-14 12:10:12 UTC
openssh-6.6.1p1-7.fc21 has been pushed to the Fedora 21 stable repository.  If problems still persist, please make note of it in this bug report.

Comment 34 dac.override 2014-11-29 08:35:01 UTC
I seem to be hitting some bug that *may or may* not be related to this. My system configuration has diverged from stock Fedora to the point where i can't tell for sure without trying it in stock config

The problem i see is when (confined) root logs in via ssh, for some reason "a" sshd process runs with sysadm's selinux credentials instead of sshd's credentials

Things seem to work fine with ordinary users

Again, this may not be related to this patch. Because besides this patch i am also using a modified /etc/pam.d/systemd-user (one with pam_selinux added to the stack to make the systemd session daemons run with the users credentials instead of the systems credentials)

A way to test this would be to map root to sysadm_u, and then to try logging in with ssh. AVC denials may occur where comm=sshd and scontext=sysadm_u:sysadm_r:sysadm_t:s0-s0:c0.c1023. if that is the case then it's more likely due to this patch

Comment 35 dac.override 2014-11-29 09:21:49 UTC
I can speculate

Does sshd re-exec it self? The debug log seems to imply that it does?

could it be that this is where sshd gets confused? it re-execs itself but uses the context that pam tells it to use for uid root?

I would assume that it knows not to consult pam for the execution context if it concerns a re-exec?

I think sshd re-execs itself but since pam would tell it the context for root is sysadm_u:sysadm_r:sysadm_t, that if it would listen to pam it would re-exec itself with that content. which would cause sshd to run with sysadm_u:sysadm_r:sysadm_t (at least temporary)

Comment 36 dac.override 2014-11-29 09:24:13 UTC
The question would then be: why does this only happen when root logs in? and not when unpriv users log in?

Comment 37 dac.override 2014-11-29 10:23:36 UTC
Yes i think i confirmed this..

I know sshd (re-)execs itself:

avc:  granted  { execute } for  pid=1446 comm="sshd" name="sshd" dev="dm-0" ino=1184435 scontext=sys.u:sys.r:sshd.common_subject tcontext=sys.u:sys.r:sshd.bin_object tclass=file

And i know that, since sshd runs as root, it wants to (re-)exec itself with the credentials pam tells it to use for user root.

But pam_selinux is called in /etc/pam.d/sshd, and so if sshd asks pam_selinux: "hey, what context do i needed to associate with root?", then pam_selinux will say: "sysadm.u:sysadm.r:sysadm.common_subject"

And then sshd end ups (re-)execing itself with "sysadm.u:sysadm.r:sysadm.common_subject" instead of the proper "sys.u:sys.r:sshd.common_subject"

Here is the proof:

avc:  granted  { dyntransition } for  pid=1446 comm="sshd" scontext=sys.u:sys.r:sshd.common_subject tcontext=sysadm.u:sysadm.r:sysadm.common_subject tclass=process

There is a difference between opening a ssh session on behalf of a user, and (re-)execing.

We can;t have sshd running with user SELinux credentials

Comment 38 Petr Lautrbach 2015-03-11 12:39:15 UTC
(In reply to dac.override from comment #37)
> Yes i think i confirmed this..
> 
...
> 
> We can;t have sshd running with user SELinux credentials


Please see https://bugzilla.redhat.com/show_bug.cgi?id=1169149#c1

Comment 39 Dominick Grift 2015-03-11 14:08:29 UTC
I saw it and i disagree.

The way i see it this is just a bug, and this argument:

"Yes, to change the context for the user session, the sshd process must be unrestricted."

To me is just utterly wrong. It works fine as long as the user log-in is not root. What makes root any different from other users in this perspective?

Anyhow, I said what i think needs to be said. If you all cannot or will not acknowledge the issue then i suppose it is case closed.


Note You need to log in before you can comment on or make changes to this bug.