Bug 2093355
| Summary: | AVCs when trying to execute a command through qemu-ga ("guest-exec" command) | ||
|---|---|---|---|
| Product: | Red Hat Enterprise Linux 8 | Reporter: | Renaud Métrich <rmetrich> |
| Component: | selinux-policy | Assignee: | Zdenek Pytela <zpytela> |
| Status: | CLOSED ERRATA | QA Contact: | Milos Malik <mmalik> |
| Severity: | medium | Docs Contact: | Jan Fiala <jafiala> |
| Priority: | medium | ||
| Version: | 8.6 | CC: | amepatil, apeetham, coli, demeng, gfialova, jinzhao, juzhang, lvrabec, marcandre.lureau, mmalik, phou, qizhu, virt-maint, zpytela |
| Target Milestone: | rc | Keywords: | Triaged |
| Target Release: | 8.9 | Flags: | jafiala:
needinfo+
jafiala: needinfo+ pm-rhel: mirror+ |
| Hardware: | All | ||
| OS: | Linux | ||
| Whiteboard: | |||
| Fixed In Version: | selinux-policy-3.14.3-118.el8 | Doc Type: | Enhancement |
| Doc Text: |
.New SELinux boolean to allow QEMU Guest Agent executing confined commands
Previously, commands that were supposed to execute in a confined context through the QEMU Guest Agent daemon program, such as `mount`, failed with an Access Vector Cache (AVC) denial. To be able to execute these commands, the `guest-agent` must run in the `virt_qemu_ga_unconfined_t` domain.
Therefore, this update adds the SELinux policy boolean `virt_qemu_ga_run_unconfined` that allows `guest-agent` to make the transition to `virt_qemu_ga_unconfined_t` for executables located in any of the following directories:
* `/etc/qemu-ga/fsfreeze-hook.d/`
* `/usr/libexec/qemu-ga/fsfreeze-hook.d/`
* `/var/run/qemu-ga/fsfreeze-hook.d/`
In addition, the necessary rules for transitions for the `qemu-ga` daemon have been added to the SELinux policy boolean.
As a result, you can now execute confined commands through the QEMU Guest Agent without AVC denials by enabling the `virt_qemu_ga_run_unconfined` boolean.
|
Story Points: | --- |
| Clone Of: | Environment: | ||
| Last Closed: | 2023-11-14 15:47:42 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: | |||
Try to reproduce it on qemu side but didn't reproduce this issue. will try to run it on libvirt side. And actually, if /etc/sysconfig/qemu-ga file changed, qga.service should've been restarted, btw. maybe you did that but didn't write it down there, if the whole operations are correct and configurations are well. Yes sorry I restarts the service after changing /etc/sysconfig/qemu-ga. (In reply to Renaud Métrich from comment #2) > Yes sorry I restarts the service after changing /etc/sysconfig/qemu-ga. okay, I got it. Could you please provide the XML file you used to boot up VM? it would be better for us to reproduce the same issue. See discussion "qemu-ga guest-exec & SELinux" from selinux-fedora List: https://lists.fedoraproject.org/archives/list/selinux@lists.fedoraproject.org/thread/LWL4WVO42KVFGZZDXATPBUDTPU36S5BK/ Daniel Berrange said: "IMHO execution of external commands should only be allowed after toggling a SELinux boolean tunable." It looks like we should find a selinux solution. In Fedora first, before it can be backported. I am moving the bug back to selinux. Thanks I think there is no need for any additional SELinux boolean as long as the child of the service in charge of executing the command runs in the "unconfined domain". Merged in rawhide, we will consider it to backport to rhel 8.8 or 8.9. the new pck should not be ready yet right? I was testing 'selinux-policy-38.1.23-1.el9' but there is no active booleans at all. This BZ is filed against RHEL-8. @demeng , please use the latest selinux-policy build for RHEL-8: selinux-policy-3.14.3-128.el8 Hi all, After executing the above steps as comment 16&37&39, I paste some output and results here, but the final result is that I couldn't execute qga command 'guest-exec' successfully. output: [root@vm-73-228 ~]# semanage fcontext -l | grep virt_qemu_ga_unco /etc/qemu-ga/fsfreeze-hook.d(/.*)? all files system_u:object_r:virt_qemu_ga_unconfined_exec_t:s0 /usr/libexec/qemu-ga/fsfreeze-hook.d(/.*)? all files system_u:object_r:virt_qemu_ga_unconfined_exec_t:s0 /usr/local/bin/qemu-quest-agent-wrapper all files system_u:object_r:virt_qemu_ga_unconfined_exec_t:s0 /var/run/qemu-ga/fsfreeze-hook.d(/.*)? all files system_u:object_r:virt_qemu_ga_unconfined_exec_t:s0 results: {"execute":"guest-exec","arguments":{"path":"qemu-quest-agent-wrapper","arg":["mount","-l"],"input-data":"","capture-output":true}} {"error": {"class": "CommandNotFound", "desc": "Command guest-exec has been disabled"}} {"execute":"guest-exec-status","arguments":{"pid":948}} {"error": {"class": "CommandNotFound", "desc": "Command guest-exec-status has been disabled"}} anything is not correct? or does it require libvirt only? I believe that the mount command is usually present on RHEL machines. Which means that the CommandNotFound error belongs to the qemu-quest-agent-wrapper command. Did you create the qemu-quest-agent-wrapper file? (In reply to dehanmeng from comment #44) > (In reply to Milos Malik from comment #43) > > I believe that the mount command is usually present on RHEL machines. Which > > means that the CommandNotFound error belongs to the qemu-quest-agent-wrapper > > command. > > > > Did you create the qemu-quest-agent-wrapper file? > > [root@vm-73-228 selinux-policy]# cat /usr/local/bin/qemu-quest-agent-wrapper > #!/bin/sh > > echo "$(basename $0) executing as $(id -Z)" > exec "${@:-}" > > anything I need to change? I believe no need for a change, but check permissions+context of the wrapper and look for AVC denials if there are any: ls -lZ /usr/local/bin/qemu-quest-agent-wrapper ausearch -i -m avc,user_avc,selinux_err,user_selinux_err -ts today Is the searched path configured comewhere? Isn't it necessary to include full path instead of just the wrapper name? execute":"guest-exec","arguments":{"path":"qemu-quest-agent-wrapper","arg":["mount","-l"],"input-data":"","capture-output":true}} (In reply to Zdenek Pytela from comment #45) > (In reply to dehanmeng from comment #44) > > (In reply to Milos Malik from comment #43) > > > I believe that the mount command is usually present on RHEL machines. Which > > > means that the CommandNotFound error belongs to the qemu-quest-agent-wrapper > > > command. > > > > > > Did you create the qemu-quest-agent-wrapper file? > > > > [root@vm-73-228 selinux-policy]# cat /usr/local/bin/qemu-quest-agent-wrapper > > #!/bin/sh > > > > echo "$(basename $0) executing as $(id -Z)" > > exec "${@:-}" > > > > anything I need to change? > > I believe no need for a change, but check permissions+context of the wrapper > and look for AVC denials if there are any: > > ls -lZ /usr/local/bin/qemu-quest-agent-wrapper [root@vm-73-228 ~]# ls -lZ /usr/local/bin/qemu-quest-agent-wrapper -rwxr-xr-x. 1 root root unconfined_u:object_r:virt_qemu_ga_unconfined_exec_t:s0 69 Aug 28 17:59 /usr/local/bin/qemu-quest-agent-wrapper > ausearch -i -m avc,user_avc,selinux_err,user_selinux_err -ts today [root@vm-73-228 ~]# ausearch -i -m avc,user_avc,selinux_err,user_selinux_err -ts today <no matches> > > Is the searched path configured comewhere? Isn't it necessary to include > full path instead of just the wrapper name? > execute":"guest-exec","arguments":{"path":"qemu-quest-agent-wrapper","arg": > ["mount","-l"],"input-data":"","capture-output":true}} I actually tested it with both absolute/relative path, and always get that error. LGTM 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 The needinfo request[s] on this closed bug have been removed as they have been unresolved for 120 days |
Description of problem: We have a customer trying to execute commands through qemu-agent, similarly to what VMWare provides with "vmrun": -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- $ virsh qemu-agent-command domain '{"execute":"guest-exec", ... -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- Commands that are supposed to execute in a confined context (e.g. "mount") fail due to an AVC popping up: -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- type=PROCTITLE msg=audit(06/03/2022 15:39:26.449:72) : 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(06/03/2022 15:39:26.449:72) : arch=x86_64 syscall=execve success=no exit=EACCES(Permission denied) a0=0x55bff8ef9df9 a1=0x55bff8ed6780 a2=0x7ffeb34343a8 a3=0x8 items=0 ppid=1603 pid=1605 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(06/03/2022 15:39:26.449:72) : avc: denied { execute } for pid=1605 comm=qemu-ga name=mount dev="dm-0" ino=33712610 scontext=system_u:system_r:virt_qemu_ga_t:s0 tcontext=system_u:object_r:mount_exec_t:s0 tclass=file permissive=0 -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< -------- This happens because the service, executing as "virt_qemu_ga_t", cannot execute commands because of missing rules in the policy (here above for "mount_exec_t"). The solution is similar to what was implemented for VMTools (BZ #1667016): we need to have a transition happening in qemu-ga when executing a command to something like "virt_qemu_ga_unconfined_t". This of course requires changes in the SELinux policy. Please sync with them. Version-Release number of selected component (if applicable): qemu-guest-agent-6.2.0-11.module+el8.6.0+14707+5aa4b42d.x86_64 How reproducible: Always Steps to Reproduce: 1. Disable blacklisting in /etc/sysconfig/qemu-ga #BLACKLIST_RPC=... 2. Restart the service 3. Execute a command from the host Actual results: AVC Expected results: No AVC Additional infos: A workaround (but it's not a viable solution in the long term) is to execute the service as an unconfined domain, e.g. "unconfined_service_t", which can be achieved using a shell script wrapper.