Bug 1633389
| Summary: | libvirt creating qemu channels with the wrong permissions | |||
|---|---|---|---|---|
| Product: | Red Hat Enterprise Linux 7 | Reporter: | Ryan Barry <rbarry> | |
| Component: | libvirt | Assignee: | Ján Tomko <jtomko> | |
| Status: | CLOSED ERRATA | QA Contact: | jiyan <jiyan> | |
| Severity: | urgent | Docs Contact: | ||
| Priority: | urgent | |||
| Version: | 7.6 | CC: | dfediuck, dyuan, fjin, jdenemar, jiyan, jsuchane, michal.skrivanek, mtessun, mzamazal, pmatyas, rbarry, virt-bugs, virt-maint, xuzhang, yafu | |
| Target Milestone: | rc | Keywords: | Regression, ZStream | |
| Target Release: | 7.6 | |||
| Hardware: | Unspecified | |||
| OS: | Unspecified | |||
| Whiteboard: | ||||
| Fixed In Version: | libvirt-4.5.0-11.el7 | Doc Type: | If docs needed, set a value | |
| Doc Text: | Story Points: | --- | ||
| Clone Of: | ||||
| : | 1634775 1635228 (view as bug list) | Environment: | ||
| Last Closed: | 2019-08-06 13:14:02 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: | 1632759, 1634765, 1634775, 1635228, 1651787 | |||
This may affects all chardev that uses unix socket as source I can reproduce this since libvirt-4.5.0.
Test this scenario in libvirt-4.5.0-1.el7.x86_64:
# rpm -qa libvirt qemu-kvm-rhev
qemu-kvm-rhev-2.12.0-18.el7.x86_64
libvirt-4.5.0-1.el7.x86_64
# uname -r
3.10.0-954.el7.x86_64
# virsh start test1
Domain test1 started
# virsh dumpxml test1 |grep "<channel" -A5
<channel type='unix'>
<source mode='bind' path='/var/lib/libvirt/qemu/channel/target/domain-2-test1/com.redhat.rhevm.vdsm'/>
<target type='virtio' name='com.redhat.rhevm.vdsm' state='disconnected'/>
<alias name='channel0'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>
# ll -alZ /var/lib/libvirt/qemu/channel/target/domain-2-test1/com.redhat.rhevm.vdsm
srwxr-xr-x. root root system_u:object_r:svirt_image_t:s0:c971,c982 /var/lib/libvirt/qemu/channel/target/domain-2-test1/com.redhat.rhevm.vdsm
Test this scenario in libvirt-4.4.0-2.el7.x86_64:
# rpm -qa qemu-kvm-rhev libvirt
libvirt-4.4.0-2.el7.x86_64
qemu-kvm-rhev-2.12.0-18.el7.x86_64
# uname -r
3.10.0-954.el7.x86_64
# virsh start normal
Domain normal started
# virsh dumpxml normal |grep "<channel" -A5
<channel type='unix'>
<source mode='bind' path='/var/lib/libvirt/qemu/channel/target/domain-1-normal/com.redhat.rhevm.vdsm'/>
<target type='virtio' name='com.redhat.rhevm.vdsm' state='disconnected'/>
<alias name='channel0'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>
# ll -alZ /var/lib/libvirt/qemu/channel/target/domain-1-normal/com.redhat.rhevm.vdsm
srwxrwxr-x. qemu qemu system_u:object_r:svirt_image_t:s0:c103,c841 /var/lib/libvirt/qemu/channel/target/domain-1-normal/com.redhat.rhevm.vdsm
Qemu process accesses chardev unix socket by fd passed by libvirtd(since RHEL7.6), which means qemu doesn't need permission to access the socket. I don’t understand why root:root permission can be an issue for vdsm. Check permission of guest agent socket file: # ll /var/lib/libvirt/qemu/channel/target/domain-22-avocado-vt-vm1/org.qemu.guest_agent.0 srwxr-xr-x. 1 root root 0 Sep 27 12:03 /var/lib/libvirt/qemu/channel/target/domain-22-avocado-vt-vm1/org.qemu.guest_agent.0 Check guest agent function by "virsh domtime", it works well. # virsh domtime avocado-vt-vm1 Time: 1538021810 Check qemu command line: #ps aux|grep qemu .... -chardev socket,id=charchannel0,**fd=29**,server,nowait -device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=org.qemu.guest_agent.0 ... (In reply to Fangge Jin from comment #6) > Qemu process accesses chardev unix socket by fd passed by libvirtd(since > RHEL7.6), which means qemu doesn't need permission to access the socket. I > don’t understand why root:root permission can be an issue for vdsm. because qemu is not the only thing connecting to it. From "the other side" vdsm is connecting to the same socket in order to talk to the guest device (agent) Looks like a side effect of using fd-passing for channels. Previously QEMU was creating the sockets while now they are created by libvirt and QEMU just gets a corresponding file descriptor. Proposed upstream patch: https://www.redhat.com/archives/libvir-list/2018-September/msg01400.html Fixed upstream by:
commit d6b8838dd83697f721fe0706068df765148154de
Author: Ján Tomko <jtomko>
CommitDate: 2018-10-02 12:44:44 +0200
security: dac: also label listen UNIX sockets
We switched to opening mode='bind' sockets ourselves:
commit 30fb2276d88b275dc2aad6ddd28c100d944b59a5
qemu: support passing pre-opened UNIX socket listen FD
in v4.5.0-rc1~251
Then fixed qemuBuildChrChardevStr to change libvirtd's label
while creating the socket:
commit b0c6300fc42bbc3e5eb0b236392f7344581c5810
qemu: ensure FDs passed to QEMU for chardevs have correct SELinux labels
v4.5.0-rc1~52
Also add labeling of these sockets to the DAC driver.
Instead of duplicating the logic which decides whether libvirt should
pre-create the socket, assume an existing path meaning that it was created
by libvirt.
https://bugzilla.redhat.com/show_bug.cgi?id=1633389
Signed-off-by: Ján Tomko <jtomko>
Reviewed-by: Erik Skultety <eskultet>
git describe: v4.8.0-19-gd6b8838dd8
I just realized that the fix in comment 14 does not consider the difference between libvirtd's and qemu's umask. Followup upstream patch: https://www.redhat.com/archives/libvir-list/2018-October/msg00198.html Followup patch pushed upstream as:
commit 8ba65c4d95712b54362fd81c34bae99f51d45a0b
Author: Ján Tomko <jtomko>
CommitDate: 2018-10-03 16:26:08 +0200
qemu: fix up permissions for pre-created UNIX sockets
My commit d6b8838 fixed the uid:gid for the pre-created UNIX sockets
but did not account for the different umask of libvirtd and QEMU.
Since commit 0e1a1a8c we set umask to '0002' for the QEMU process.
Manually tune-up the permissions to match what we would have gotten
if QEMU had created the socket.
https://bugzilla.redhat.com/show_bug.cgi?id=1633389
Signed-off-by: Ján Tomko <jtomko>
Reviewed-by: Jiri Denemark <jdenemar>
git describe: v4.8.0-22-g8ba65c4d95
Version:
libvirt-4.5.0-11.el7.x86_64
qemu-kvm-rhev-2.12.0-25.el7.x86_64
kernel-3.10.0-1031.el7.x86_64
Steps:
1. Prepare a VM with these two kinds of unix socket devices
# virsh domstate avocado-vt-vm1
shut off
# virsh dumpxml avocado-vt-vm1 |grep "<serial" -A17
<serial type='unix'>
<source mode='bind' path='/tmp/foo'/>
<target type='isa-serial' port='1'>
<model name='isa-serial'/>
</target>
</serial>
<console type='unix'>
<source mode='bind' path='/tmp/foo'/>
<target type='serial' port='1'/>
</console>
<channel type='unix'>
<target type='virtio' name='com.redhat.rhevm.vdsm'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>
2. Start VM, check the dumpxml and qemu cmd line of VM
# virsh start avocado-vt-vm1
Domain avocado-vt-vm1 started
# virsh dumpxml avocado-vt-vm1 |grep "<serial" -A17
<serial type='unix'>
<source mode='bind' path='/tmp/foo'/>
<target type='isa-serial' port='1'>
<model name='isa-serial'/>
</target>
<alias name='serial0'/>
</serial>
<console type='unix'>
<source mode='bind' path='/tmp/foo'/>
<target type='serial' port='1'/>
<alias name='serial0'/>
</console>
<channel type='unix'>
<source mode='bind' path='/var/lib/libvirt/qemu/channel/target/domain-4-avocado-vt-vm1/com.redhat.rhevm.vdsm'/>
<target type='virtio' name='com.redhat.rhevm.vdsm' state='disconnected'/>
<alias name='channel0'/>
<address type='virtio-serial' controller='0' bus='0' port='1'/>
</channel>
# ps -ef |grep avocado-vt-vm1 |sed 's/-device/\ndevice/g'
...
device isa-serial,chardev=charserial0,id=serial0 -chardev socket,id=charchannel0,fd=31,server,nowait
device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=com.redhat.rhevm.vdsm
...
3. According to the dumpxml configuration, check the permission of corresponding files.
# ll -alZ /tmp/foo
srwxrwxr-x. qemu qemu system_u:object_r:tmp_t:s0 /tmp/foo
# ll -alZ /var/lib/libvirt/qemu/channel/target/domain-4-avocado-vt-vm1/com.redhat.rhevm.vdsm
srwxrwxr-x. qemu qemu system_u:object_r:svirt_image_t:s0:c280,c525 /var/lib/libvirt/qemu/channel/target/domain-4-avocado-vt-vm1/com.redhat.rhevm.vdsm
The results showed in step-3 are as expected, move this bug to be verified.
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/RHSA-2019:2294 |
Description of problem: The latest versions of qemu-kvm-rhev and libvirt create channels in /var/lib/libvirt/qemu/channel which are owned by root:root instead of qemu:qemu, and these are not readable by guests. How reproducible: 100% Steps to Reproduce: 1. Install libvirt-4.5.0-10.el7 and qemu-kvm-rhev-2.12.0-18. 2. Start a guest 3. Create a channel, such as: <channel type='unix'> <source mode='bind' path='/var/lib/libvirt/qemu/channels/14182ea9-c01f-428d-ac67-5a7e2639c931.com.redhat.rhevm.vdsm'/> <target type='virtio' name='com.redhat.rhevm.vdsm' state='disconnected'/> <alias name='channel0'/> <address type='virtio-serial' controller='0' bus='0' port='1'/> </channel> Actual results: permissions are incorrect Expected results: Permissions are qemu:qemu Additional info: