-
Bug
-
Resolution: Done-Errata
-
Normal
-
rhel-9.3.0
-
selinux-policy-38.1.41-1.el9
-
None
-
Important
-
1
-
rhel-sst-security-selinux
-
ssg_security
-
20
-
None
-
QE ack
-
False
-
-
Yes
-
Red Hat Enterprise Linux
-
CY24Q2
-
-
Pass
-
Automated
-
Bug Fix
-
-
Done
-
None
Reproducer
Have a user mapped to sysadm_u and able to sudo
[root@vm-sudo9 ~]# useradd -Z sysadm_u -G wheel sysadm
[root@vm-sudo9 ~]# echo redhat | passwd --stdin sysadm
[root@vm-sudo9 ~]# semanage boolean -m --on ssh_sysadm_login
Enable sudo-io input+output logging
Defaults log_output
Defaults log_input
Defaults iolog_dir=/var/log/sudo-io
Make sure `/var/log/sudo-io` doesn't exist yet.
Issue 1
[sysadm@vm-sudo9 ~]$ sudo dmidecode
sudo: unable to open /var: Permission denied
[sysadm@vm-sudo9 ~]$
Trigger condition
ALWAYS
AVCs
type=PROCTITLE msg=audit(11/09/2023 08:46:34.833:368) : proctitle=sudo dmidecode type=SYSCALL msg=audit(11/09/2023 08:46:34.833:368) : arch=x86_64 syscall=openat success=no exit=EACCES(Permission denied) a0=AT_FDCWD a1=0x7fff7f989ef0 a2=O_RDONLY|O_NONBLOCK a3=0x0 items=0 ppid=4561 pid=29408 auid=sysadm uid=sysadm gid=sysadm euid=root suid=root fsuid=root egid=root sgid=sysadm fsgid=root tty=pts1 ses=8 comm=sudo exe=/usr/bin/sudo subj=sysadm_u:sysadm_r:sysadm_sudo_t:s0-s0:c0.c1023 key=(null) type=AVC msg=audit(11/09/2023 08:46:34.833:368) : avc: denied { read } for pid=29408 comm=sudo name=var dev="dm-0" ino=33575046 scontext=sysadm_u:sysadm_r:sysadm_sudo_t:s0-s0:c0.c1023 tcontext=system_u:object_r:var_t:s0 tclass=dir permissive=0
Root cause: `sudo` cannot read `/var` directory.
strace
4692 [sysadm_u:sysadm_r:sysadm_sudo_t:s0-s0:c0.c1023] 08:31:01.799094 openat(AT_FDCWD</home/sysadm>, "/var" [system_u:object_r:var_t:s0], O_RDONLY|O_NONBLOCK) = -1 EACCES (Permission denied) <0.000070>
Code location
# stap -d /usr/libexec/sudo/sudoers.so -d /usr/bin/sudo --ldd -v -e 'probe syscall.openat { if (execname() != "sudo" || argstr !~ "\"/var\".*O_RDONLY.*") next; printf("%s(%s)\n", name, argstr); print_usyms(ubacktrace()) }' [...] openat(AT_FDCWD, "/var", O_RDONLY|O_NONBLOCK) 0x7fb97a13e5db : open+0x5b/0x130 [/usr/lib64/libc.so.6] 0x7fb97a37ac3d : sudo_mkdir_parents_v1+0xfd/0x380 [/usr/libexec/sudo/libsudo_util.so.0.0.0] 0x7fb979fd143a : iolog_mkdirs.lto_priv.0+0x3aa/0x500 [/usr/libexec/sudo/sudoers.so] 0x7fb979fd18a7 : iolog_nextid+0x67/0x3d0 [/usr/libexec/sudo/sudoers.so] 0x7fb979f992ff : fill_seq.lto_priv.0+0x5f/0x140 [/usr/libexec/sudo/sudoers.so] 0x7fb979fd4a3d : expand_iolog_path.constprop.0+0x1cd/0x2e0 [/usr/libexec/sudo/sudoers.so] 0x7fb979fad1ae : format_iolog_path+0x10e/0x1a0 [/usr/libexec/sudo/sudoers.so] 0x7fb979fb45be : sudoers_policy_main+0x1c1e/0x3390 [/usr/libexec/sudo/sudoers.so] 0x7fb979fa29c7 : sudoers_policy_check+0xb7/0x1f0 [/usr/libexec/sudo/sudoers.so] 0x5642c7171427 : main+0x717/0x28d0 [/usr/bin/sudo] 0x7fb97a03feb0 : __libc_start_call_main+0x80/0xb0 [/usr/lib64/libc.so.6] 0x7fb97a03ff60 : __libc_start_main@GLIBC_2.2.5+0x80/0x150 [/usr/lib64/libc.so.6] 0x5642c7173605 : _start+0x25/0x30 [/usr/bin/sudo]
Source code:
49 bool 50 sudo_mkdir_parents_v1(char *path, uid_t uid, gid_t gid, mode_t mode, bool quiet) 51 { : 64 reopen: 65 dfd = open(path, O_RDONLY|O_NONBLOCK); <<<<< HERE 66 if (dfd == -1) { 67 if (errno != ENOENT) { 68 if (!quiet) 69 sudo_warn(U_("unable to open %s"), path); 70 goto bad; 71 } 72 if (mkdir(path, mode) == 0) { :
Proposed fix (CIL format)
(allow sudodomain var_t (dir (read)))
Issue 2
[sysadm@vm-sudo9 ~]$ sudo dmidecode sudo: unable to open /var: Permission denied sudo: /var/log/sudo-io/00/00/02: Permission denied sudo: error initializing I/O plugin sudoers_io
Trigger condition
`/var/log/sudo-io` exists but Proposed fix for Issue 1 not installed.
Proposed fix
Same as Proposed fix for Issue 1.
Issue 3
[sysadm@vm-sudo9 ~]$ sudo dmidecode --> NO OUTPUT [sysadm@vm-sudo9 ~]$ [sysadm@vm-sudo9 ~]$ sudo -r sysadm_r dmidecode --> NO OUTPUT [sysadm@vm-sudo9 ~]$
Trigger condition
Using recommended configuration in `/etc/sudoers` (automatic role switching):
%wheel ALL=(ALL) TYPE=sysadm_t ROLE=sysadm_r ALL
or Using default configuration + explicitly specifying the role.
AVCs
type=PROCTITLE msg=audit(11/09/2023 09:07:26.866:408) : proctitle=/sbin/dmidecode type=EXECVE msg=audit(11/09/2023 09:07:26.866:408) : argc=1 a0=/sbin/dmidecode type=SYSCALL msg=audit(11/09/2023 09:07:26.866:408) : arch=x86_64 syscall=execve success=yes exit=0 a0=0x55992069a5c0 a1=0x7ffe6f400230 a2=0x7ffe6f400240 a3=0x0 items=0 ppid=29740 pid=29741 auid=sysadm uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=8 comm=dmidecode exe=/usr/sbin/dmidecode subj=sysadm_u:sysadm_r:dmidecode_t:s0-s0:c0.c1023 key=(null) type=AVC msg=audit(11/09/2023 09:07:26.866:408) : avc: denied { read write } for pid=29741 comm=dmidecode path=/dev/pts/2 dev="devpts" ino=5 scontext=sysadm_u:sysadm_r:dmidecode_t:s0-s0:c0.c1023 tcontext=sysadm_u:object_r:devpts_t:s0 tclass=chr_file permissive=0 type=AVC msg=audit(11/09/2023 09:07:26.866:408) : avc: denied { read write } for pid=29741 comm=dmidecode path=/dev/pts/2 dev="devpts" ino=5 scontext=sysadm_u:sysadm_r:dmidecode_t:s0-s0:c0.c1023 tcontext=sysadm_u:object_r:devpts_t:s0 tclass=chr_file permissive=0 type=AVC msg=audit(11/09/2023 09:07:26.866:408) : avc: denied { read write } for pid=29741 comm=dmidecode path=/dev/pts/2 dev="devpts" ino=5 scontext=sysadm_u:sysadm_r:dmidecode_t:s0-s0:c0.c1023 tcontext=sysadm_u:object_r:devpts_t:s0 tclass=chr_file permissive=0 type=AVC msg=audit(11/09/2023 09:07:26.866:408) : avc: denied { read write } for pid=29741 comm=dmidecode path=/dev/pts/2 dev="devpts" ino=5 scontext=sysadm_u:sysadm_r:dmidecode_t:s0-s0:c0.c1023 tcontext=sysadm_u:object_r:devpts_t:s0 tclass=chr_file permissive=0
Root cause: `/dev/pts/2` mislabeled with `devpts_t` instead of `user_devpts_t`
Why this works in "normal case"
When not explicitly changing role, the command works.
This is because this leads to having `dmidecode` execute in wrong context `sysadm_sudo_t`:
29871 [sysadm_u:sysadm_r:sysadm_sudo_t:s0-s0:c0.c1023] 09:13:36.539520 execve("/sbin/dmidecode" [system_u:object_r:dmidecode_exec_t:s0], ["dmidecode"], ["HISTSIZE=10000", "HOSTNAME=vm-sudo9", "LANG=en_US.UTF-8", "LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;37;41:su=37;41:sg=30"..., "TERM=xterm-256color", "MAIL=/var/spool/mail/sysadm", "PATH=/sbin:/bin:/usr/sbin:/usr/bin", "LOGNAME=root", "USER=root", "HOME=/root", "SHELL=/bin/bash", "SUDO_COMMAND=/sbin/dmidecode", "SUDO_USER=sysadm", "SUDO_UID=1000", "SUDO_GID=1000"] <unfinished ...> : 29871 [sysadm_u:sysadm_r:sysadm_sudo_t:s0-s0:c0.c1023] 09:13:36.539793 <... execve resumed>) = 0 <0.000210>
In such case, there is some allow rule:
# sesearch -A -s sysadm_sudo_t -t devpts_t -c chr_file -p write allow sysadm_sudo_t devpts_t:chr_file { append ioctl lock open read setattr write };
THIS IS WRONG: processes should never execute in `sysadm_sudo_t` context at all.
This requires a proper fix in the policy.
Code location
# stap -g -d /usr/libexec/sudo/sudoers.so -d /usr/bin/sudo --ldd -v -e 'probe syscall.chown { if (execname() != "sudo" || argstr !~ "/dev/pts/") next; printf("%s(%s)\n", name, argstr); print_usyms(ubacktrace()); raise(%{SIGSTOP%}); mdelay(2000) }' [...] chown("/dev/pts/2", 0, 5) 0x7feda7a3e99b : chown+0xb/0x30 [/usr/lib64/libc.so.6] 0x558bbb95a54e : exec_pty.constprop.0+0x113e/0x2390 [/usr/bin/sudo] 0x558bbb9511ec : run_command.constprop.0+0x11c/0x360 [/usr/bin/sudo] 0x558bbb944424 : main+0x2714/0x28d0 [/usr/bin/sudo] 0x7feda7a3feb0 : __libc_start_call_main+0x80/0xb0 [/usr/lib64/libc.so.6] 0x7feda7a3ff60 : __libc_start_main@GLIBC_2.2.5+0x80/0x150 [/usr/lib64/libc.so.6] 0x558bbb944605 : _start+0x25/0x30 [/usr/bin/sudo] # gdb /usr/bin/sudo <PID> [...] (gdb) bt #0 0x00007feda7a3e99b in chown () from /lib64/libc.so.6 #1 0x0000558bbb95a54e in get_pty (leader=<optimized out>, follower=<optimized out>, name=<optimized out>, namesz=4096, ttyuid=0) at ./get_pty.c:66 #2 pty_setup (details=<optimized out>, tty=0x558bbcc8c764 "/dev/pts/1") at ./exec_pty.c:150 #3 exec_pty.constprop.0 (cstat=0x7ffc71a12e50, details=<optimized out>) at ./exec_pty.c:1368 #4 0x0000558bbb9511ec in sudo_execute (details=0x558bbb969600 <command_details.lto_priv>, cstat=0x7ffc71a12e50) at ./exec.c:402 #5 run_command (details=0x558bbb969600 <command_details.lto_priv>) at ./sudo.c:977 #6 0x0000558bbb944424 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at ./sudo.c:305
Source code:
54 bool 55 get_pty(int *leader, int *follower, char *name, size_t namesz, uid_t ttyuid) 56 { 57 struct group *gr; 58 gid_t ttygid = -1; 59 bool ret = false; 60 debug_decl(get_pty, SUDO_DEBUG_PTY); 61 62 if ((gr = getgrnam("tty")) != NULL) 63 ttygid = gr->gr_gid; 64 65 if (openpty(leader, follower, name, NULL, NULL) == 0) { 66 if (chown(name, ttyuid, ttygid) == 0) <<<<< HERE 67 ret = true; 68 } 69 70 debug_return_bool(ret); 71 }
We have `openpty()` return a PTY with unexpected context `devpts_t`.
Proposed fix (TE format)
policy_module(sudodomain_devpts_t, 1.0) gen_require(` type user_devpts_t; attribute sudodomain; ') term_create_pty(sudodomain, user_devpts_t) allow sudodomain user_devpts_t:chr_file { setattr rw_chr_file_perms };
(Stolen from `policy/modules/system/userdomain.te` for `confined_admindomain`)
- links to
-
RHBA-2024:130707 selinux-policy bug fix and enhancement update