Bug 1535109
| Summary: | gpg-agent does not work when user is confined (user_u or staff_u) | ||
|---|---|---|---|
| Product: | Red Hat Enterprise Linux 7 | Reporter: | Jonathan Billings <jsbillin> |
| Component: | selinux-policy | Assignee: | Lukas Vrabec <lvrabec> |
| Status: | CLOSED ERRATA | QA Contact: | Milos Malik <mmalik> |
| Severity: | medium | Docs Contact: | |
| Priority: | medium | ||
| Version: | 7.4 | CC: | lvrabec, mmalik, plautrba, rdulhani, rmetrich, ssekidde |
| Target Milestone: | rc | ||
| Target Release: | --- | ||
| Hardware: | x86_64 | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | selinux-policy-3.13.1-203.el7 | Doc Type: | If docs needed, set a value |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2019-08-06 12:51:45 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: | |||
| Bug Depends On: | |||
| Bug Blocks: | 1653106 | ||
The reproducer for staff_u user triggers many SELinux denials in enforcing mode. Here is the audit2allow summary: #============= gpg_agent_t ============== allow gpg_agent_t apm_bios_t:chr_file getattr; allow gpg_agent_t autofs_device_t:chr_file getattr; allow gpg_agent_t clock_device_t:chr_file getattr; allow gpg_agent_t console_device_t:chr_file getattr; allow gpg_agent_t devlog_t:sock_file getattr; allow gpg_agent_t event_device_t:chr_file getattr; allow gpg_agent_t fixed_disk_device_t:blk_file getattr; allow gpg_agent_t framebuf_device_t:chr_file getattr; allow gpg_agent_t fuse_device_t:chr_file getattr; #!!!! This avc can be allowed using the boolean 'domain_can_write_kmsg' allow gpg_agent_t kmsg_device_t:chr_file getattr; allow gpg_agent_t kvm_device_t:chr_file getattr; allow gpg_agent_t loop_control_device_t:chr_file getattr; allow gpg_agent_t memory_device_t:chr_file getattr; allow gpg_agent_t netcontrol_device_t:chr_file getattr; allow gpg_agent_t nvram_device_t:chr_file getattr; allow gpg_agent_t ppp_device_t:chr_file getattr; allow gpg_agent_t ptmx_t:chr_file getattr; allow gpg_agent_t tty_device_t:chr_file getattr; allow gpg_agent_t uhid_device_t:chr_file getattr; allow gpg_agent_t usb_device_t:chr_file getattr; allow gpg_agent_t usbmon_device_t:chr_file getattr; allow gpg_agent_t vhost_device_t:chr_file getattr; allow gpg_agent_t xserver_misc_device_t:chr_file getattr; #============= gpg_pinentry_t ============== allow gpg_pinentry_t gpg_secret_t:sock_file getattr; # rpm -qa selinux\* gnupg\* | sort gnupg2-2.0.22-4.el7.x86_64 selinux-policy-3.13.1-183.el7.noarch selinux-policy-targeted-3.13.1-183.el7.noarch # The reproducer for staff_u user triggers additional SELinux denial in permissive mode:
----
type=PROCTITLE msg=audit(01/17/2018 01:45:58.043:555) : proctitle=/usr/bin/pinentry-curses
type=SYSCALL msg=audit(01/17/2018 01:45:58.043:555) : arch=x86_64 syscall=utime success=yes exit=0 a0=0x1c850f0 a1=0x0 a2=0x7ffdedb6d6c0 a3=0x7ffdedb6d060 items=0 ppid=8135 pid=8176 auid=staff-user uid=staff-user gid=staff-user euid=staff-user suid=staff-user fsuid=staff-user egid=staff-user sgid=staff-user fsgid=staff-user tty=(none) ses=4 comm=pinentry-curses exe=/usr/bin/pinentry-curses subj=staff_u:staff_r:gpg_pinentry_t:s0-s0:c0.c1023 key=(null)
type=AVC msg=audit(01/17/2018 01:45:58.043:555) : avc: denied { write } for pid=8176 comm=pinentry-curses name=S.gpg-agent dev="vda1" ino=12583996 scontext=staff_u:staff_r:gpg_pinentry_t:s0-s0:c0.c1023 tcontext=staff_u:object_r:gpg_secret_t:s0 tclass=sock_file permissive=1
----
and produces following files:
$ ls -Z /home/staff-user/.gnupg/
drwx------. staff-user staff-user staff_u:object_r:gpg_secret_t:s0 private-keys-v1.d
-rw-------. staff-user staff-user staff_u:object_r:gpg_secret_t:s0 pubring.gpg
-rw-------. staff-user staff-user staff_u:object_r:gpg_secret_t:s0 pubring.gpg~
-rw-------. staff-user staff-user staff_u:object_r:gpg_secret_t:s0 random_seed
-rw-------. staff-user staff-user staff_u:object_r:gpg_secret_t:s0 secring.gpg
srwxrwxr-x. staff-user staff-user staff_u:object_r:gpg_secret_t:s0 S.gpg-agent
-rw-------. staff-user staff-user staff_u:object_r:gpg_secret_t:s0 trustdb.gpg
$
The reproducer for user_u user triggers the same SELinux denials but they contain "user_u:user:" instead of "staff_u:staff_r:" strings. For example:
----
type=PROCTITLE msg=audit(01/17/2018 02:00:16.333:825) : proctitle=/usr/bin/pinentry-curses
type=SYSCALL msg=audit(01/17/2018 02:00:16.333:825) : arch=x86_64 syscall=utime success=yes exit=0 a0=0x121d0f0 a1=0x0 a2=0x7ffd1f147640 a3=0x7ffd1f146fe0 items=0 ppid=8333 pid=8348 auid=user-user uid=user-user gid=user-user euid=user-user suid=user-user fsuid=user-user egid=user-user sgid=user-user fsgid=user-user tty=(none) ses=5 comm=pinentry-curses exe=/usr/bin/pinentry-curses subj=user_u:user_r:gpg_pinentry_t:s0 key=(null)
type=AVC msg=audit(01/17/2018 02:00:16.333:825) : avc: denied { write } for pid=8348 comm=pinentry-curses name=S.gpg-agent dev="vda1" ino=23069025 scontext=user_u:user_r:gpg_pinentry_t:s0 tcontext=user_u:object_r:gpg_secret_t:s0 tclass=sock_file permissive=1
----
type=PROCTITLE msg=audit(01/17/2018 02:00:16.333:824) : proctitle=/usr/bin/pinentry-curses
type=SYSCALL msg=audit(01/17/2018 02:00:16.333:824) : arch=x86_64 syscall=stat success=yes exit=0 a0=0x121d0f0 a1=0x7ffd1f147640 a2=0x7ffd1f147640 a3=0x7ffd1f146fe0 items=0 ppid=8333 pid=8348 auid=user-user uid=user-user gid=user-user euid=user-user suid=user-user fsuid=user-user egid=user-user sgid=user-user fsgid=user-user tty=(none) ses=5 comm=pinentry-curses exe=/usr/bin/pinentry-curses subj=user_u:user_r:gpg_pinentry_t:s0 key=(null)
type=AVC msg=audit(01/17/2018 02:00:16.333:824) : avc: denied { getattr } for pid=8348 comm=pinentry-curses path=/home/user-user/.gnupg/S.gpg-agent dev="vda1" ino=23069025 scontext=user_u:user_r:gpg_pinentry_t:s0 tcontext=user_u:object_r:gpg_secret_t:s0 tclass=sock_file permissive=1
----
----
type=PROCTITLE msg=audit(04/29/2019 07:53:38.013:1408) : proctitle=gpg --gen-key
type=SYSCALL msg=audit(04/29/2019 07:53:38.013:1408) : arch=x86_64 syscall=socket success=yes exit=4 a0=netlink a1=SOCK_RAW a2=igp a3=0x7ffd71627220 items=0 ppid=1353 pid=1395 auid=user21061 uid=user21061 gid=staff-user euid=user21061 suid=user21061 fsuid=user21061 egid=staff-user sgid=staff-user fsgid=staff-user tty=pts1 ses=21 comm=gpg exe=/usr/bin/gpg2 subj=staff_u:staff_r:gpg_t:s0-s0:c0.c1023 key=(null)
type=AVC msg=audit(04/29/2019 07:53:38.013:1408) : avc: denied { create } for pid=1395 comm=gpg scontext=staff_u:staff_r:gpg_t:s0-s0:c0.c1023 tcontext=staff_u:staff_r:gpg_t:s0-s0:c0.c1023 tclass=netlink_audit_socket permissive=1
----
type=PROCTITLE msg=audit(04/29/2019 07:53:38.013:1409) : proctitle=gpg --gen-key
type=SOCKADDR msg=audit(04/29/2019 07:53:38.013:1409) : saddr={ fam=netlink nlnk-fam=16 nlnk-pid=0 }
type=SYSCALL msg=audit(04/29/2019 07:53:38.013:1409) : arch=x86_64 syscall=sendmsg success=yes exit=18 a0=0x4 a1=0x7ffd71627e60 a2=0x0 a3=0x7ffd71627220 items=0 ppid=1353 pid=1395 auid=user21061 uid=user21061 gid=staff-user euid=user21061 suid=user21061 fsuid=user21061 egid=staff-user sgid=staff-user fsgid=staff-user tty=pts1 ses=21 comm=gpg exe=/usr/bin/gpg2 subj=staff_u:staff_r:gpg_t:s0-s0:c0.c1023 key=(null)
type=AVC msg=audit(04/29/2019 07:53:38.013:1409) : avc: denied { nlmsg_relay } for pid=1395 comm=gpg scontext=staff_u:staff_r:gpg_t:s0-s0:c0.c1023 tcontext=staff_u:staff_r:gpg_t:s0-s0:c0.c1023 tclass=netlink_audit_socket permissive=1
type=AVC msg=audit(04/29/2019 07:53:38.013:1409) : avc: denied { write } for pid=1395 comm=gpg scontext=staff_u:staff_r:gpg_t:s0-s0:c0.c1023 tcontext=staff_u:staff_r:gpg_t:s0-s0:c0.c1023 tclass=netlink_audit_socket permissive=1
----
----
type=PROCTITLE msg=audit(04/29/2019 07:53:38.013:1408) : proctitle=gpg --gen-key
type=SYSCALL msg=audit(04/29/2019 07:53:38.013:1408) : arch=x86_64 syscall=socket success=yes exit=4 a0=netlink a1=SOCK_RAW a2=igp a3=0x7ffd71627220 items=0 ppid=1353 pid=1395 auid=user21061 uid=user21061 gid=staff-user euid=user21061 suid=user21061 fsuid=user21061 egid=staff-user sgid=staff-user fsgid=staff-user tty=pts1 ses=21 comm=gpg exe=/usr/bin/gpg2 subj=staff_u:staff_r:gpg_t:s0-s0:c0.c1023 key=(null)
type=AVC msg=audit(04/29/2019 07:53:38.013:1408) : avc: denied { create } for pid=1395 comm=gpg scontext=staff_u:staff_r:gpg_t:s0-s0:c0.c1023 tcontext=staff_u:staff_r:gpg_t:s0-s0:c0.c1023 tclass=netlink_audit_socket permissive=1
----
type=PROCTITLE msg=audit(04/29/2019 07:53:38.013:1409) : proctitle=gpg --gen-key
type=SOCKADDR msg=audit(04/29/2019 07:53:38.013:1409) : saddr={ fam=netlink nlnk-fam=16 nlnk-pid=0 }
type=SYSCALL msg=audit(04/29/2019 07:53:38.013:1409) : arch=x86_64 syscall=sendmsg success=yes exit=18 a0=0x4 a1=0x7ffd71627e60 a2=0x0 a3=0x7ffd71627220 items=0 ppid=1353 pid=1395 auid=user21061 uid=user21061 gid=staff-user euid=user21061 suid=user21061 fsuid=user21061 egid=staff-user sgid=staff-user fsgid=staff-user tty=pts1 ses=21 comm=gpg exe=/usr/bin/gpg2 subj=staff_u:staff_r:gpg_t:s0-s0:c0.c1023 key=(null)
type=AVC msg=audit(04/29/2019 07:53:38.013:1409) : avc: denied { nlmsg_relay } for pid=1395 comm=gpg scontext=staff_u:staff_r:gpg_t:s0-s0:c0.c1023 tcontext=staff_u:staff_r:gpg_t:s0-s0:c0.c1023 tclass=netlink_audit_socket permissive=1
type=AVC msg=audit(04/29/2019 07:53:38.013:1409) : avc: denied { write } for pid=1395 comm=gpg scontext=staff_u:staff_r:gpg_t:s0-s0:c0.c1023 tcontext=staff_u:staff_r:gpg_t:s0-s0:c0.c1023 tclass=netlink_audit_socket permissive=1
----
# rpm -qa pgp\* gpg\* selinux\* | sort
gpgme-1.3.2-5.el7.x86_64
gpg-pubkey-352c64e5-52ae6884
selinux-policy-3.13.1-244.el7.noarch
selinux-policy-devel-3.13.1-244.el7.noarch
selinux-policy-targeted-3.13.1-244.el7.noarch
#
commit 56a226ff0fa985b3635f8157d4f014f53a973d8b (HEAD -> rhel7.7-base, origin/rhel7.7-base)
Author: Lukas Vrabec <lvrabec>
Date: Sat May 18 00:55:20 2019 +0200
Update userdomains to allow confined users to create gpg keys
Resolves: rhbz#1535109
commit f9f55b936e1ba08fe1483f8ea333289dc533095c (HEAD -> rhel7.7-contrib, origin/rhel7.7-contrib)
Author: Lukas Vrabec <lvrabec>
Date: Sat May 18 00:49:45 2019 +0200
Update gpg policy to make ti working with confined users
Resolves: rhbz#1535109
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, 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-2019:2127 |
Description of problem: There is a problem with the default SELinux policy for GPG when run as a Confined user. It prevents the pinentry from collecting a password. user_u and staff_u are restricted from getattr() on many files in /etc, which I'm ignoring because it doesn't seem to affect the ability of gpg to run, but there are several paths that seem to be blocked by selinux that prevents gpg-agent from operating. Version-Release number of selected component (if applicable): selinux-policy-targeted-3.13.1-166.el7_4.7.noarch gnupg2-2.0.22-4.el7.x86_64 How reproducible: Always Steps to Reproduce: 1. Make sure your user is confined (id -Z should not be unconfined_u) 2. eval $(gpg-agent --daemon) 3. gpg --gen-key Actual results: -bash-4.2$ id -Z user_u:user_r:user_t:s0 -bash-4.2$ eval $(gpg-agent --daemon) -bash-4.2$ gpg --gen-key gpg (GnuPG) 2.0.22; Copyright (C) 2013 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) Your selection? 1 RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) Requested keysize is 2048 bits Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n years Key is valid for? (0) 1y Key expires at Wed 16 Jan 2019 10:53:06 AM EST Is this correct? (y/N) y GnuPG needs to construct a user ID to identify your key. Real name: test user Email address: test Comment: You selected this USER-ID: "test user <test>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O You need a Passphrase to protect your secret key. gpg: cancelled by user gpg: Key generation canceled. -bash-4.2$ Expected results: -bash-4.2$ id -Z user_u:user_r:user_t:s0 -bash-4.2$ eval $(gpg-agent --daemon) -bash-4.2$ gpg --gen-key gpg (GnuPG) 2.0.22; Copyright (C) 2013 Free Software Foundation, Inc. This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) Your selection? 1 RSA keys may be between 1024 and 4096 bits long. What keysize do you want? (2048) Requested keysize is 2048 bits Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n years Key is valid for? (0) 1y Key expires at Wed 16 Jan 2019 11:00:31 AM EST Is this correct? (y/N) y GnuPG needs to construct a user ID to identify your key. Real name: test user Email address: test Comment: You selected this USER-ID: "test user <test>" Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O You need a Passphrase to protect your secret key. [prompting for password from pinentry-curses] We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. We need to generate a lot of random bytes. It is a good idea to perform some other action (type on the keyboard, move the mouse, utilize the disks) during the prime generation; this gives the random number generator a better chance to gain enough entropy. gpg: key B1887542 marked as ultimately trusted public and secret key created and signed. gpg: checking the trustdb gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model gpg: depth: 0 valid: 2 signed: 0 trust: 0-, 0q, 0n, 0m, 0f, 2u gpg: next trustdb check due at 2019-01-16 pub 2048R/B1887542 2018-01-16 [expires: 2019-01-16] Key fingerprint = AE37 D8B6 0C17 4CBE 483A DAB1 5C4B D5ED B188 7542 uid test user <test> sub 2048R/D4CAEB32 2018-01-16 [expires: 2019-01-16] Additional info: I've created a custom policy module that fixes this for our users: # cat local_gpg.te module local_gpg 1.0; require { type staff_t; type user_t; type gpg_t; type gpg_agent_tmp_t; type gpg_agent_t; type gpg_pinentry_t; class process { noatsecure rlimitinh siginh }; class netlink_audit_socket { create nlmsg_relay write }; class sock_file { getattr write }; class dir { getattr search }; } #============= gpg_agent_t ============== allow gpg_agent_t gpg_pinentry_t:process { noatsecure rlimitinh siginh }; #============= gpg_pinentry_t ============== allow gpg_pinentry_t gpg_agent_tmp_t:dir search; allow gpg_pinentry_t gpg_agent_tmp_t:sock_file { getattr write }; #============= gpg_t ============== allow gpg_t self:netlink_audit_socket { create nlmsg_relay write }; #============= staff_t ============== allow staff_t gpg_t:process { noatsecure rlimitinh siginh }; allow user_t gpg_t:process { noatsecure rlimitinh siginh };