Bug 1910077
| Summary: | sudoing as sysadm_r still requires specifying "-r sysadm_r" parameter | ||
|---|---|---|---|
| Product: | Red Hat Enterprise Linux 8 | Reporter: | Renaud Métrich <rmetrich> |
| Component: | sudo | Assignee: | Radovan Sroka <rsroka> |
| Status: | CLOSED WONTFIX | QA Contact: | BaseOS QE Security Team <qe-baseos-security> |
| Severity: | high | Docs Contact: | |
| Priority: | high | ||
| Version: | 8.3 | CC: | bwelterl, daniel.j.arevalo.ctr, dapospis, kwalker, lvrabec, miturria, mmalik, pkhedeka, plautrba, wdh, zpytela |
| Target Milestone: | rc | Keywords: | Triaged |
| Target Release: | 8.0 | Flags: | pm-rhel:
mirror+
|
| Hardware: | All | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | Doc Type: | If docs needed, set a value | |
| Doc Text: | Story Points: | --- | |
| Clone Of: | Environment: | ||
| Last Closed: | 2021-12-01 12:33:15 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: | |||
Hi,
Please consider this RFE with highest priority, I never stop getting cases where customers try to use "sudo <command>" from a confined user and the command fails, due to "<command>" executing in the context of sudo ("sysadm_sudo_t") instead of the user which sudo'ed (usually "sysadm_t").
Implementing this would solve **ALL** "sudo <command>" cases in one shot (and keep the policy "sane").
See also BZ #1943572.
Renaud.
I'm not sure if this is relevant but why is the output the same? [sysadm_user@ci-vm-10-0-136-149 ~]$ sudo id -Z sysadm_u:sysadm_r:sysadm_t:s0-s0:c0.c1023 [sysadm_user@ci-vm-10-0-136-149 ~]$ sudo -r sysadm_r id -Z sysadm_u:sysadm_r:sysadm_t:s0-s0:c0.c1023 "Inheritance" seems to be working in this case or am I missing something? Hi Radovan, Yes, the output *looks* the same, but it's due to having some internal transition from *sysadm_sudo_t* to *sysadm_t* when executing "id -Z" (because it's labeled with *bin_t*). Generally this transition won't happen because executables (e.g. "passwd") are *not* labeled with *bin_t*. See example below with my "strace+selinux" tool not yet available upstream (but on https://people.redhat.com/rmetrich/strace-selinux/): 1. As root, monitor the bash executing as the confined "sysadm_t" user # ./strace.el8 --secontext -fttTvyy -o sudo.strace -p 1519 2. As the "sysadm_t" user $ echo $$ 1519 $ sudo id -Z 3. As root, stop strace and check the transitions happening # grep -A 1 " execve(" sudo.strace -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- 1593 [sysadm_t] 15:32:41.439739 execve("/usr/bin/sudo" [sudo_exec_t], ["sudo", "id", "-Z"], ["LS_COLORS=rs=0:di=38;5;33:ln=38;"..., "SSH_CONNECTION=192.168.122.1 471"..., "LANG=en_US.UTF-8", "HISTCONTROL=ignoredups", "HOSTNAME=vm-confined83", "SSH_AUTH_SOCK=/tmp/ssh-F8oslCyf8"..., "XDG_SESSION_ID=3", "USER=sysadm", "SELINUX_ROLE_REQUESTED=", "PWD=/home/sysadm", "SSH_ASKPASS=/usr/libexec/openssh"..., "HOME=/home/sysadm", "SSH_CLIENT=192.168.122.1 47128 2"..., "SELINUX_LEVEL_REQUESTED=", "XDG_DATA_DIRS=/home/sysadm/.loca"..., "SSH_TTY=/dev/pts/1", "MAIL=/var/spool/mail/sysadm", "TERM=xterm-256color", "SHELL=/bin/bash", "XMODIFIERS=@im=none", "SELINUX_USE_CURRENT_RANGE=", "SHLVL=1", "LOGNAME=sysadm", "DBUS_SESSION_BUS_ADDRESS=unix:pa"..., "XDG_RUNTIME_DIR=/run/user/1002", "PATH=/home/sysadm/.local/bin:/ho"..., "HISTSIZE=1000", "LESSOPEN=||/usr/bin/lesspipe.sh "..., "_=/usr/bin/sudo"]) = 0 <0.008430> 1593 [sysadm_sudo_t] 15:32:41.448588 access("/etc/suid-debug", F_OK) = -1 ENOENT (No such file or directory) <0.000071> -- 1599 [sysadm_sudo_t] 15:32:41.528704 execve("/usr/sbin/unix_chkpwd" [chkpwd_exec_t], ["/usr/sbin/unix_chkpwd", "sysadm", "chkexpiry"], []) = 0 <0.000494> 1599 [chkpwd_t] 15:32:41.529446 access("/etc/suid-debug", F_OK) = -1 ENOENT (No such file or directory) <0.000029> -- 1602 [sysadm_sudo_t] 15:32:41.564430 execve("/bin/id" [bin_t], ["id", "-Z"], ["LS_COLORS=rs=0:di=38;5;33:ln=38;"..., "LANG=en_US.UTF-8", "HOSTNAME=vm-confined83", "MAIL=/var/spool/mail/sysadm", "TERM=xterm-256color", "HISTSIZE=1000", "PATH=/sbin:/bin:/usr/sbin:/usr/b"..., "LOGNAME=root", "USER=root", "HOME=/root", "SHELL=/bin/bash", "SUDO_COMMAND=/bin/id -Z", "SUDO_USER=sysadm", "SUDO_UID=1002", "SUDO_GID=1002"] <unfinished ...> -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- Above, we see that at the time "id -Z" started executing, we were "sysadm_sudo_t", which is *wrong* and causes all the issues with admin executables (except "bin_t" and a few that have transitions hardcoded in the policy). 4. Do the same test for "sudo -r" $ echo $$ 1519 # ./strace.el8 --secontext -fttTvyy -o sudo.role_strace -p 1519 $ sudo -r sysadm_r id -Z 5. Check the transitions # grep -A 1 " execve(" sudo.role.strace -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- 1848 [sysadm_t] 16:24:17.372987 execve("/usr/bin/sudo" [sudo_exec_t], ["sudo", "-r", "sysadm_r", "/var/tmp/foo"], ["LS_COLORS=rs=0:di=38;5;33:ln=38;"..., "SSH_CONNECTION=192.168.122.1 427"..., "LANG=en_US.UTF-8", "HISTCONTROL=ignoredups", "HOSTNAME=vm-confined83", "SSH_AUTH_SOCK=/tmp/ssh-WNhcVhjrP"..., "XDG_SESSION_ID=3", "USER=sysadm", "SELINUX_ROLE_REQUESTED=", "PWD=/home/sysadm", "SSH_ASKPASS=/usr/libexec/openssh"..., "HOME=/home/sysadm", "SSH_CLIENT=192.168.122.1 42770 2"..., "SELINUX_LEVEL_REQUESTED=", "XDG_DATA_DIRS=/home/sysadm/.loca"..., "SSH_TTY=/dev/pts/1", "MAIL=/var/spool/mail/sysadm", "TERM=xterm-256color", "SHELL=/bin/bash", "XMODIFIERS=@im=none", "SELINUX_USE_CURRENT_RANGE=", "SHLVL=1", "LOGNAME=sysadm", "DBUS_SESSION_BUS_ADDRESS=unix:pa"..., "XDG_RUNTIME_DIR=/run/user/1002", "PATH=/home/sysadm/.local/bin:/ho"..., "HISTSIZE=1000", "LESSOPEN=||/usr/bin/lesspipe.sh "..., "_=/usr/bin/sudo"]) = 0 <0.000878> 1848 [sysadm_sudo_t] 16:24:17.374749 access("/etc/suid-debug", F_OK) = -1 ENOENT (No such file or directory) <0.000048> -- 1853 [sysadm_sudo_t] 16:24:17.466709 execve("/usr/sbin/unix_chkpwd" [chkpwd_exec_t], ["/usr/sbin/unix_chkpwd", "sysadm", "chkexpiry"], []) = 0 <0.000466> 1853 [chkpwd_t] 16:24:17.467453 access("/etc/suid-debug", F_OK) = -1 ENOENT (No such file or directory) <0.000035> -- 1854 [sysadm_sudo_t] 16:24:17.496996 execve("/usr/libexec/sudo/sesh" [shell_exec_t], ["sesh", "/var/tmp/foo"], ["LS_COLORS=rs=0:di=38;5;33:ln=38;"..., "LANG=en_US.UTF-8", "HOSTNAME=vm-confined83", "MAIL=/var/spool/mail/sysadm", "TERM=xterm-256color", "HISTSIZE=1000", "PATH=/sbin:/bin:/usr/sbin:/usr/b"..., "LOGNAME=root", "USER=root", "HOME=/root", "SHELL=/bin/bash", "SUDO_COMMAND=/var/tmp/foo", "SUDO_USER=sysadm", "SUDO_UID=1002", "SUDO_GID=1002"] <unfinished ...> 1848 [sysadm_sudo_t] 16:24:17.498209 <... ppoll resumed>) = 1 ([{fd=8, revents=POLLHUP}]) <0.001825> -- 1854 [sysadm_t] 16:24:17.507680 execve("/var/tmp/foo" [user_tmp_t], ["/var/tmp/foo"], ["LS_COLORS=rs=0:di=38;5;33:ln=38;"..., "LANG=en_US.UTF-8", "HOSTNAME=vm-confined83", "MAIL=/var/spool/mail/sysadm", "TERM=xterm-256color", "HISTSIZE=1000", "PATH=/sbin:/bin:/usr/sbin:/usr/b"..., "LOGNAME=root", "USER=root", "HOME=/root", "SHELL=/bin/bash", "SUDO_COMMAND=/var/tmp/foo", "SUDO_USER=sysadm", "SUDO_UID=1002", "SUDO_GID=1002"]) = 0 <0.000241> 1854 [sysadm_t] 16:24:17.507973 brk(NULL) = 0x561efdc6f000 <0.000011> -- 1855 [sysadm_t] 16:24:17.518411 execve("/bin/id" [bin_t], ["id"], ["LS_COLORS=rs=0:di=38;5;33:ln=38;"..., "LANG=en_US.UTF-8", "SUDO_GID=1002", "HOSTNAME=vm-confined83", "SUDO_COMMAND=/var/tmp/foo", "USER=root", "PWD=/home/sysadm", "HOME=/root", "SUDO_USER=sysadm", "SUDO_UID=1002", "MAIL=/var/spool/mail/sysadm", "SHELL=/bin/bash", "TERM=xterm-256color", "SHLVL=1", "LOGNAME=root", "PATH=/sbin:/bin:/usr/sbin:/usr/b"..., "HISTSIZE=1000", "_=/bin/id"]) = 0 <0.000180> -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- Here above, we see that "/usr/libexec/sudo/sesh" executed, which moved the context from "sysadm_sudo_t" to "sysadm_t". Then later "id -Z" executed from already being "sysadm_t", no remained "sysadm_t". This is what we want (or at least would like) by default for everything executed by sudo: at the time the admin command executes (e.g. "passwd"), we need to already be "sysadm_t". This will avoir hardcoding transitions from "sysadm_sudo_t" to (e.g. "passwd_t") in the policy. BZs this BZ could solve (non exhaustive list!!!): - https://bugzilla.redhat.com/show_bug.cgi?id=1943572 - https://bugzilla.redhat.com/show_bug.cgi?id=1920883 - https://bugzilla.redhat.com/show_bug.cgi?id=1919122 - https://bugzilla.redhat.com/show_bug.cgi?id=1917879 I'm afraid it is not that straight forward as it may be seen at the first glance. If -r is not specified the /usr/libexec/sudo/sesh is not called at all so there's completely different mechanism of SELinux handling. I guess we need some help from SELinux guys to see the proper way of transitioning the roles. Changing the behavior unconditionally may cause some other issues, like mainly security ones. For some reason, the problem magically disappeared in RHEL7; NOT RHEL8: RHEL7: [pimpampet@rhel79 ~]$ id -Z sysadm_u:sysadm_r:sysadm_t:s0-s0:c0.c1023 [pimpampet@rhel79 ~]$ sudo yum check-update Loaded plugins: product-id, search-disabled-repos, subscription-manager [pimpampet@rhel79 ~]$ rpm -qi selinux-policy Name : selinux-policy Version : 3.13.1 Release : 268.el7_9.2 Architecture: noarch Install Date: Tue 08 Dec 2020 01:54:29 PM CET Group : System Environment/Base Size : 6911 License : GPLv2+ Signature : RSA/SHA256, Fri 30 Oct 2020 05:18:13 PM CET, Key ID 199e2f91fd431d51 Source RPM : selinux-policy-3.13.1-268.el7_9.2.src.rpm Build Date : Fri 30 Oct 2020 04:34:55 PM CET Build Host : x86-vm-29.build.eng.bos.redhat.com Relocations : (not relocatable) Packager : Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla> Vendor : Red Hat, Inc. URL : http://oss.tresys.com/repos/refpolicy/ Summary : SELinux policy configuration Description : SELinux Reference Policy - modular. Based off of reference policy: Checked out revision 2.20091117 RHEL8: pimpampet@rhel84 ~]$ id -Z sysadm_u:sysadm_r:sysadm_t:s0-s0:c0.c1023 [pimpampet@rhel84 ~]$ sudo dnf check-update error: cannot open Packages database in /var/lib/rpm Error: Error: rpmdb open failed [pimpampet@rhel84 ~]$ sudo -r sysadm_r dnf check-update Updating Subscription Management repositories. Last metadata expiration check: 0:23:39 ago on Thu 27 May 2021 08:35:54 AM CEST. [pimpampet@rhel84 ~]$ rpm -qi selinux-policy Name : selinux-policy Version : 3.14.3 Release : 67.el8 Architecture: noarch Install Date: Thu 27 May 2021 08:40:54 AM CEST Group : Unspecified Size : 24919 License : GPLv2+ Signature : RSA/SHA256, Wed 17 Mar 2021 10:04:46 AM CET, Key ID 199e2f91fd431d51 Source RPM : selinux-policy-3.14.3-67.el8.src.rpm Build Date : Tue 16 Mar 2021 07:54:57 PM CET Build Host : s390-059.build.eng.bos.redhat.com Relocations : (not relocatable) Packager : Red Hat, Inc. <http://bugzilla.redhat.com/bugzilla> Vendor : Red Hat, Inc. URL : https://github.com/fedora-selinux/selinux-policy Summary : SELinux policy configuration Description : SELinux Base package for SELinux Reference Policy - modular. Based off of reference policy: Checked out revision 2.20091117 There bugzillas linked in the Internal-links section. This is a list of all related, resolved bzs: https://bugzilla.redhat.com/show_bug.cgi?id=1917879 https://bugzilla.redhat.com/show_bug.cgi?id=1919122 https://bugzilla.redhat.com/show_bug.cgi?id=1920883 https://bugzilla.redhat.com/show_bug.cgi?id=1943572 https://bugzilla.redhat.com/show_bug.cgi?id=1965251 https://bugzilla.redhat.com/show_bug.cgi?id=1966945 https://bugzilla.redhat.com/show_bug.cgi?id=2000488 https://bugzilla.redhat.com/show_bug.cgi?id=2013749 https://bugzilla.redhat.com/show_bug.cgi?id=2017838 https://bugzilla.redhat.com/show_bug.cgi?id=2026598 https://bugzilla.redhat.com/show_bug.cgi?id=2031065 https://bugzilla.redhat.com/show_bug.cgi?id=2046481 https://bugzilla.redhat.com/show_bug.cgi?id=2053457 Resolution example: commit 3b826a9f34d86388fde3a07a9dcfeccdc762bafe Author: Zdenek Pytela <zpytela> Date: Mon Dec 20 11:47:29 2021 +0100 Allow sudodomains execute passwd in the passwd domain When an unprivileged user in the sysadm_r role executes passwd through sudo, it transitions into sysadm_sudo_t domain by default. With this commit, the process transitions back to sysadm_t. Resolves: rhbz#1943572 diff --git a/policy/modules/admin/sudo.if b/policy/modules/admin/sudo.if index e79eef7a8..356b150f4 100644 --- a/policy/modules/admin/sudo.if +++ b/policy/modules/admin/sudo.if @@ -98,6 +98,9 @@ template(`sudo_role_template',` kerberos_read_config($1_sudo_t) ') + optional_policy(` + usermanage_domtrans_passwd($1_sudo_t) + ') ') |
Description of problem: A sysadm user mapped to "sysadm_u" SELinux user and with "sysadm_r" role shouldn't have to specify "-r sysadm_r" to run an administrative command, as shown in the example below: -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- $ id -Z sysadm_u:sysadm_r:sysadm_t:s0-s0:c0.c1023 $ sudo dnf check-update error: cannot open Packages database in /var/lib/rpm Error: Error: rpmdb open failed --> FAIL $ sudo -r sysadm_r dnf check-update --> SUCCESS -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- Version-Release number of selected component (if applicable): sudo-1.8.29-6.el8.x86_64 How reproducible: ALWAYS Steps to Reproduce: 1. Create a sysadm user # useradd -Z sysadm_u -G wheel sysadm_user # echo "sysadm_pass" | passwd sysadm_user --stdin # semanage boolean -m ssh_sysadm_login --on 2. Login as the sysadm user # ssh sysadm_user@localhost $ id -Z sysadm_u:sysadm_r:sysadm_t:s0-s0:c0.c1023 3. Execute admin command $ sudo dnf check-update Actual results: error: cannot open Packages database in /var/lib/rpm Error: Error: rpmdb open failed Expected results: Success Additional info: Digging into the code, I can see that selinux_execve() is called only when "-r <role>" argument is passed to the command. -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- 134 #define CD_RBAC_ENABLED 0x000800 206 /* 207 * Setup the execution environment and execute the command. 208 * If SELinux is enabled, run the command via sesh, otherwise 209 * execute it directly. 210 * If the exec fails, cstat is filled in with the value of errno. 211 */ 212 void 213 exec_cmnd(struct command_details *details, int errfd) 214 { : 236 #ifdef HAVE_SELINUX 237 if (ISSET(details->flags, CD_RBAC_ENABLED)) { 238 selinux_execve(details->execfd, details->command, details->argv, 239 details->envp, ISSET(details->flags, CD_NOEXEC)); 240 } else 241 #endif 242 { 243 sudo_execve(details->execfd, details->command, details->argv, 244 details->envp, ISSET(details->flags, CD_NOEXEC)); 245 } 246 } : 250 } -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- WITHOUT "-r sysadm_r" (line 243, "sudo_execve"): -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- (gdb) bt #0 sudo_execve (fd=-1, path=0x55c1573d0a08 "/bin/dnf", argv=0x55c1574031b8, envp=0x55c1574b2c20, noexec=false) at ./exec_common.c:191 #1 0x000055c155842a35 in exec_cmnd (details=details@entry=0x55c155a621e0 <command_details>, errfd=7) at ./exec.c:243 #2 0x000055c1558468e7 in exec_nopty (details=details@entry=0x55c155a621e0 <command_details>, cstat=cstat@entry=0x7ffd1d2c4e80) at ./exec_nopty.c:401 #3 0x000055c155842f5c in sudo_execute (details=0x55c155a621e0 <command_details>, cstat=0x7ffd1d2c4e80) at ./exec.c:393 #4 0x000055c155851a3f in run_command (details=0x55c155a621e0 <command_details>) at ./sudo.c:957 #5 0x000055c155841772 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at ./sudo.c:301 (gdb) up #1 0x000055c155842a35 in exec_cmnd (details=details@entry=0x55c155a621e0 <command_details>, errfd=7) at ./exec.c:243 243 sudo_execve(details->execfd, details->command, details->argv, (gdb) p/x details->flags $2 = 0x22085 --> no CD_RBAC_ENABLED flag, hence normal sudo_execve() -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- WITH "-r sysadm_r" (line 237, "selinux_execve"): -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- (gdb) bt #0 selinux_execve (fd=-1, path=0x5566a977ca08 "/bin/dnf", argv=0x5566a97a8738, envp=0x5566a97b2610, noexec=false) at ./selinux.c:418 #1 0x00005566a79a08e3 in exec_cmnd (details=details@entry=0x5566a7bc01e0 <command_details>, errfd=7) at ./exec.c:238 #2 0x00005566a79a48e7 in exec_nopty (details=details@entry=0x5566a7bc01e0 <command_details>, cstat=cstat@entry=0x7ffcca03b370) at ./exec_nopty.c:401 #3 0x00005566a79a0f5c in sudo_execute (details=0x5566a7bc01e0 <command_details>, cstat=0x7ffcca03b370) at ./exec.c:393 #4 0x00005566a79afa3f in run_command (details=0x5566a7bc01e0 <command_details>) at ./sudo.c:957 #5 0x00005566a799f772 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at ./sudo.c:301 (gdb) up #1 0x00005566a79a08e3 in exec_cmnd (details=details@entry=0x5566a7bc01e0 <command_details>, errfd=7) at ./exec.c:238 238 selinux_execve(details->execfd, details->command, details->argv, (gdb) p/x details->flags $1 = 0x22885 --> CD_RBAC_ENABLED flag, hence selinux_execve() -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- Who sets CD_RBAC_ENABLED? -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- 633 /* 634 * Convert a command_info array into a command_details structure. 635 */ 636 static void 637 command_info_to_details(char * const info[], struct command_details *details) 638 { : 849 #ifdef HAVE_SELINUX 850 if (details->selinux_role != NULL && is_selinux_enabled() > 0) 851 SET(details->flags, CD_RBAC_ENABLED); 852 #endif 853 debug_return; 854 } -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- The test on line 850 should likely be amended to retrieve the current role using the SELinux API. The result would be to always execute selinux_execve() when SELinux is enabled. If you believe the issue is within the SELinux policy instead (since role is already "sysadm_r"), then please redirect the BZ to selinux maintainers.