Bug 2177704

Summary: Cannot add smartcard key to SSH agent when user is confined
Product: Red Hat Enterprise Linux 8 Reporter: Renaud Métrich <rmetrich>
Component: selinux-policyAssignee: Zdenek Pytela <zpytela>
Status: CLOSED ERRATA QA Contact: Milos Malik <mmalik>
Severity: high Docs Contact:
Priority: high    
Version: 8.7CC: lvrabec, mhavrila, mmalik, mmmurphy2, omoris
Target Milestone: rcKeywords: Triaged
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: selinux-policy-3.14.3-128.el8 Doc Type: Bug Fix
Doc Text:
Cause: policy does not allow ssh-agent execute openssh helper for pkcs#11 support Consequence: ssh-agent cannot access keys stored on a smart card Fix: required rules were added to the policy Result: ssh-agent can get a key stored on a smart card for ssh to use it
Story Points: ---
Clone Of: Environment:
Last Closed: 2023-11-14 15:47:46 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 Renaud Métrich 2023-03-13 12:41:06 UTC
Description of problem:

We have a customer trying to add the key from a smartcard to the SSH agent from a confined user (staff_u):
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
$ ssh-add -s /usr/lib64/pkcs11/opensc-pkcs11.so
Enter passphrase for PKCS#11: <Enter card PIN>
Could not add card "/usr/lib64/pkcs11/opensc-pkcs11.so": agent refused operation
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

After requesting the PIN, the request is sent to the agent but agent denies it, because of the following AVCs happening on the agent socket:
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
... : proctitle=/usr/libexec/openssh/ssh-pkcs11-helper
[...]
... : avc:  denied  { read write } for  pid=423099 comm=ssh-pkcs11-help path=socket:[2348810] dev="sockfs" ino=2348810 scontext=staff_u:staff_r:staff_t:s0-s0:c0.c1023 tcontext=staff_u:staff_r:staff_ssh_agent_t:s0-s0:c0.c1023 tclass=unix_stream_socket permissive=0
[...]
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

The root cause for this is the helper /usr/libexec/openssh/ssh-pkcs11-helper is labeled with *bin_t*, which causes a transition to *staff_t* to happen when the helper gets executed by the SSH agent, the latter running with *staff_ssh_agent_t* context:

-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
423099 [staff_u:staff_r:staff_ssh_agent_t:s0-s0:c0.c1023] 07:38:36.431721 dup2(6<UNIX:[2348812->2348811]> [staff_u:staff_r:staff_ssh_agent_t:s0-s0:c0.c1023], 0</dev/null<char 1:3>> [system_u:object_r:null_device_t:s0]) = 0<UNIX:[2348812->2348811]> [staff_u:staff_r:staff_ssh_agent_t:s0-s0:c0.c1023] <0.000031>
423099 [staff_u:staff_r:staff_ssh_agent_t:s0-s0:c0.c1023] 07:38:36.432172 dup2(6<UNIX:[2348812->2348811]> [staff_u:staff_r:staff_ssh_agent_t:s0-s0:c0.c1023], 1</dev/null<char 1:3>> [system_u:object_r:null_device_t:s0] <unfinished ...>
423099 [staff_u:staff_r:staff_ssh_agent_t:s0-s0:c0.c1023] 07:38:36.432412 <... dup2 resumed>) = 1<UNIX:[2348812->2348811]> [staff_u:staff_r:staff_ssh_agent_t:s0-s0:c0.c1023] <0.000084>
 :
423099 [staff_u:staff_r:staff_ssh_agent_t:s0-s0:c0.c1023] 07:38:36.433326 execve("/usr/libexec/openssh/ssh-pkcs11-helper" [system_u:object_r:bin_t:s0], ["/usr/libexec/openssh/ssh-pkcs11-helper"], ...
423099 [staff_u:staff_r:staff_t:s0-s0:c0.c1023] 07:38:36.434977 <... execve resumed>) = 0 <0.001052>
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

See above last line, we see the context switching, due to transition below:
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
# sesearch -T -s staff_ssh_agent_t -t bin_t
type_transition staff_ssh_agent_t bin_t:process staff_t;
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

Later, the helper reads the socket (on STDIN) but due to the AVC, doesn't read anything, causing the failure:
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
423099 [staff_u:staff_r:staff_t:s0-s0:c0.c1023] 07:38:36.773758 poll([{fd=0</null> [system_u:object_r:null_device_t:s0!!system_u:object_r:default_t:s0], events=POLLIN}, {fd=1</null> [system_u:object_r:null_device_t:s0!!system_u:object_r:default_t:s0], events=0}], 2, -1) = 1 ([{fd=0, revents=POLLIN}]) <0.000024>
423099 [staff_u:staff_r:staff_t:s0-s0:c0.c1023] 07:38:36.773986 read(0</null> [system_u:object_r:null_device_t:s0!!system_u:object_r:default_t:s0], "", 16384) = 0 <0.000021>
423099 [staff_u:staff_r:staff_t:s0-s0:c0.c1023] 07:38:36.774156 exit_group(0) = ?
423099 [staff_u:staff_r:staff_t:s0-s0:c0.c1023] 07:38:36.774651 +++ exited with 0 +++
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

The issue is likely in Upstream policy as well.

The corresponding rules in the policy leading to the transition are the ones below:
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
 337 template(`ssh_role_template',`
 :
 410         # transition back to normal privs upon exec
 411         corecmd_shell_domtrans($1_ssh_agent_t, $3)
 412         orecmd_bin_domtrans($1_ssh_agent_t, $3)
 :

policy/modules/roles/unprivuser.te:    ssh_role_template(user, user_r, user_t)
policy/modules/roles/unprivuser.te:        ssh_role_template(user, user_r, user_t)
policy/modules/roles/sysadm.te:    ssh_role_template(sysadm, sysadm_r, sysadm_t)
policy/modules/roles/staff.te:    ssh_role_template(staff, staff_r, staff_t)
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

There are hence 2 possibilities:

1. either the helper should continue executing in the context of the caller, staff_ssh_agent_t

2. or rules must be added for SELinux users to be able to read/write the socket, but I would consider this is a security flaw

Version-Release number of selected component (if applicable):

selinux-policy-3.14.3-108.el8_7.1.noarch
Probably Upstream as well

How reproducible:

Always, but don't have a smartcard to test

Comment 4 Zdenek Pytela 2023-08-11 16:31:06 UTC
Commit to backport:
71086d81c (HEAD -> rawhide, upstream/rawhide) Label /usr/libexec/openssh/ssh-pkcs11-helper with ssh_agent_exec_t

Comment 9 Zdenek Pytela 2023-08-15 07:53:44 UTC
Ondro,

Can you help us with verification that fix for this bz is complete? It requires confined users setup and access to a smart card.

Comment 20 errata-xmlrpc 2023-11-14 15:47:46 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory (selinux-policy bug fix and enhancement update), and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2023:7091