-
Bug
-
Resolution: Unresolved
-
Major
-
None
-
rhel-8.9.0
-
None
-
Major
-
sst_security_selinux
-
ssg_security
-
False
-
-
-
All
New boolean `virt_qemu_ga_run_unconfined` was introduced in in RHEL 8.9 as part of the BZ https://bugzilla.redhat.com/show_bug.cgi?id=2093355
This was done to help `qemu-guest-agent` run the command on the host which were otherwise denied by SELinux since `qemu-guest-agent` used to run in a confined context `virt_qemu_ga_t`.
It was meant to transition it to to `virt_qemu_ga_unconfined_t` which is unconfined.
type_transition virt_qemu_ga_t virt_qemu_ga_unconfined_exec_t:process virt_qemu_ga_unconfined_t; [ virt_qemu_ga_run_unconfined ]:True
I tested with the new boolean on RHEL 8.9 with the latest `qemu-guest-agent` and `selinux-policy` package and still see Permission error and AVC to execute the mount command even with the boolean `virt_qemu_ga_run_unconfined` enabled
$ virsh --connect qemu:///system qemu-agent-command rhel8.9-selinux '{"execute": "guest-exec", "arguments": { "path": "/usr/bin/mount", "arg": [ "-v" , "/dev/vda1" , "/boot" ], "capture-output": true }}' error: internal error: unable to execute QEMU agent command 'guest-exec': Guest agent command failed, error was 'Failed to execute child process “/usr/bin/mount” (Permission denied)'
I see that the AVC for `execute` permission for the `qemu-ga` daemon service
---- type=PROCTITLE msg=audit(04/02/2024 06:57:31.026:101) : proctitle=/usr/bin/qemu-ga --method=virtio-serial --path=/dev/virtio-ports/org.qemu.guest_agent.0 --blacklist= -F/etc/qemu-ga/fsfreeze-hoo type=SYSCALL msg=audit(04/02/2024 06:57:31.026:101) : arch=x86_64 syscall=execve success=no exit=EACCES(Permission denied) a0=0x55d3e273f9a0 a1=0x55d3e275dda0 a2=0x7ffef2fa2038 a3=0x8 items=0 ppid=5541 pid=5872 auid=unset uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=(none) ses=unset comm=qemu-ga exe=/usr/bin/qemu-ga subj=system_u:system_r:virt_qemu_ga_t:s0 key=(null) type=AVC msg=audit(04/02/2024 06:57:31.026:101) : avc: denied { execute } for pid=5872 comm=qemu-ga name=mount dev="dm-0" ino=13187661 scontext=system_u:system_r:virt_qemu_ga_t:s0 tcontext=system_u:object_r:mount_exec_t:s0 tclass=file permissive=0 ----
I have removed the blacklist before testing to allow the `guest-exec` to work.
[root@rhel8 ~]# cat /etc/sysconfig/qemu-ga | grep BLACKLIST #BLACKLIST_RPC=guest-file-open,guest-file-close,guest-file-read,guest-file-write,guest-file-seek,guest-file-flush,guest-exec,guest-exec-status [root@rhel8 ~]# ps -elf | grep qemu-ga 4 S root 5541 1 0 80 0 - 33817 x64_sy 06:42 ? 00:00:00 /usr/bin/qemu-ga --method=virtio-serial --path=/dev/virtio-ports/org.qemu.guest_agent.0 --blacklist= -F/etc/qemu-ga/fsfreeze-hook 0 S root 6127 5379 0 80 0 - 3036 - 07:24 pts/0 00:00:00 grep --color=auto qemu-ga
Looking at the strace collected while the command was being run, I see that, the `qemu-ga` running in `virt_qemu_ga_t` is directly trying to execute the `mount` command instead of first transitioning to `virt_qemu_ga_unconfined_t` context.
5872 [system_u:system_r:virt_qemu_ga_t:s0] 06:57:31.027001 close(11<pipe:[35494]> [system_u:system_r:virt_qemu_ga_t:s0]) = 0 <0.000005> 5872 [system_u:system_r:virt_qemu_ga_t:s0] 06:57:31.027022 rt_sigaction(SIGPIPE, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0x7fb986d94cf0}, NULL, 8) = 0 <0.000005> 5872 [system_u:system_r:virt_qemu_ga_t:s0] 06:57:31.027043 execve("/usr/bin/mount" [system_u:object_r:mount_exec_t:s0], ["/usr/bin/mount", "-v", "/dev/vda1", "/boot"], ["LANG=en_US.UTF-8", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin", "INVOCATION_ID=d9a81befc77847fbb6fea254bbf14532", "JOURNAL_STREAM=9:35101", "FSFREEZE_HOOK_PATHNAME=/etc/qemu-ga/fsfreeze-hook"]) = -1 EACCES (Permission denied) <0.000102> 5872 [system_u:system_r:virt_qemu_ga_t:s0] 06:57:31.027215 write(7<pipe:[35492]> [system_u:system_r:virt_qemu_ga_t:s0], "\1\0\0\0", 4) = 4 <0.000009> 5541 [system_u:system_r:virt_qemu_ga_t:s0] 06:57:31.027239 <... read resumed>"\1\0\0\0", 8) = 4 <0.001234> 5872 [system_u:system_r:virt_qemu_ga_t:s0] 06:57:31.027247 write(7<pipe:[35492]> [system_u:system_r:virt_qemu_ga_t:s0], "\r\0\0\0", 4 <unfinished ...>
Earlier in the previous Bugzilla comment 16 (https://bugzilla.redhat.com/show_bug.cgi?id=2093355#c16) rmetrich had suggest that we use wrapper script which will help transition this context , however I see that mount command is being directly executed rather than through a wrapper in the strace.
Because `virt_qemu_ga_t` is not directly allowed to execute mount commands, this causes the AVC.
What were you trying to do that didn't work?
qemu-guest-agent is not able to execute the mount command because its not transitioning to the unconfined context even when the boolean `virt_qemu_ga_run_unconfined` is enabled before executing the command.
See also above notes for observation about the issue.
Please provide the package NVR for which bug is seen:
[root@rhel8 ~]# rpm -qa | grep selinux-policy selinux-policy-targeted-3.14.3-128.el8_9.1.noarch selinux-policy-3.14.3-128.el8_9.1.noarch
How reproducible:
Everytime
Steps to reproduce
- Enable boolean `virt_qemu_ga_run_unconfined` on RHEL 8.9 guest with the latest SELinux policy rpms.
# yum update selinux-policy\* -y # semanage boolean --modify --on virt_qemu_ga_run_unconfined # semanage boolean --list | grep virt_qemu_ga_run_unconfined
- Disable blacklisting of `guest-exec` command in the guest in file /etc/sysconfig/qemu-ga and restart the service
# sed -e -i.backup 's/BLACKLIST/#BLACKLIST/' /etc/sysconfig/qemu-ga # systemctl restart qemu-guest-agent # ps -elf | grep qemu-ga
- Execute the command on the host.
virsh --connect qemu:///system qemu-agent-command <guest-vm-name> '{"execute": "guest-exec", "arguments": { "path": "/usr/bin/mount", "arg": [ "-v" , "/dev/vda1" , "/boot" ], "capture-output": true }}'
Expected results
The virsh qemu-agent command execute successfully when boolean is enabled.
Actual results
The virsh qemu-agent command execute fails even when boolean is enabled.