Bug 1665400

Summary: Libvirt reports SEV feature as unsupported even though the platform provides the feature
Product: Red Hat Enterprise Linux 8 Reporter: Erik Skultety <eskultet>
Component: libvirtAssignee: Erik Skultety <eskultet>
Status: CLOSED CURRENTRELEASE QA Contact: Luyao Huang <lhuang>
Severity: medium Docs Contact:
Priority: high    
Version: 8.0CC: chhu, dyuan, eskultet, jdenemar, jiyan, knoel, rbalakri, virt-bugs, wchadwic, xuzhang, yalzhang
Target Milestone: rc   
Target Release: 8.0   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: libvirt-4.5.0-21.el8 Doc Type: Bug Fix
Doc Text:
Cause: Restrictive default permissions on /dev/sev device Consequence: Machines requiring the SEV security feature would not start because libvirt would think the feature is unsupported (because of the permissions). Fix: Libvirt overrides the file system permissions in order for QEMU to detect the SEV feature Result: Machines requiring the SEV feature can be successfully started by libvirt
Story Points: ---
Clone Of:
: 1665469 1671791 (view as bug list) Environment:
Last Closed: 2019-06-14 01:58:21 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: 1665469, 1672188    
Bug Blocks: 1501607, 1654309, 1671791    

Description Erik Skultety 2019-01-11 09:48:06 UTC
Description of problem:
Libvirt reports <sev supported='no'/> even though SEV is enabled on the platform, i.e. both the cpuflags contain 'sev' and /dev/sev exists on the filesystem. 

Version-Release number of selected component (if applicable):
4.5.0-17.module+el8+2625+db702f9d

How reproducible:


Steps to Reproduce:
1. enable SEV on the platform so that /dev/sev appears on the filesystem
2. install libvirt, launch libvirtd
3. run virsh domcapabilities, the output contains:
...
<sev supported='no'/>
...

Actual results:
Libvirt is unable to launch a SEV VM because it reports the feature as unsupported

Expected results:
Libvirt is able to launch a SEV VM

Additional info:
1) Going through libvirt debug logs, one can also see that the error is coming from QEMU when probing for capabilities:

debug : qemuMonitorJSONIOProcessLine:197 : Line [{"id": "libvirt-53", "error": {"class": "GenericError", "desc": "SEV feature is not available"}}]

2) Even though 1) suggests this might be a bug in QEMU, the problem are the default permissions on /dev/sev:

# ls -l /dev/sev
crw-------. 1 root root

which is a problem because when libvirt probes QEMU for capabilities, the process runs as qemu:qemu by default.

Comment 7 Erik Skultety 2019-01-31 15:33:40 UTC
Upstream patches for libvirt posted:
https://www.redhat.com/archives/libvir-list/2019-January/msg01343.html

Comment 8 Erik Skultety 2019-02-01 11:51:25 UTC
Fixed upstream by:

commit a2d3dea9d41dba313d9566120a8ec9d358567bd0                                                                                                                               
Refs: v5.0.0-198-ga2d3dea9d4                                                                                             
Author:     Erik Skultety <eskultet>                                                                                                                               
AuthorDate: Thu Jan 24 10:33:01 2019 +0100                                                                                                                                    
Commit:     Erik Skultety <eskultet>                                                                                                                               
CommitDate: Fri Feb 1 12:44:28 2019 +0100                                                                                                                                     

    qemu: caps: Use CAP_DAC_OVERRIDE for probing to avoid permission issues

    This is mainly about /dev/sev and its default permissions 0600. Of
    course, rule of 'tinfoil' would be that we can't trust anything, but the
    probing code in QEMU is considered safe from security's perspective + we
    can't create an udev rule for this at the moment, because ioctls and
    file system permissions aren't cross-checked in kernel and therefore a
    user with read permissions could issue a 'privileged' operation on SEV
    which is currently only limited to root.

    https://bugzilla.redhat.com/show_bug.cgi?id=1665400

    Signed-off-by: Erik Skultety <eskultet>                                                                                                                        
    Reviewed-by: Daniel P. Berrangé <berrange>

Comment 12 Luyao Huang 2019-02-11 02:52:40 UTC
Verify this bug with libvirt-4.5.0-21.module+el8+2777+e17f6250.x86_64:

1. check /dev/sev device permission:

# ll -Z /dev/sev 
crw-------. 1 root root system_u:object_r:sev_device_t:s0 10, 58 Feb  9 13:14 /dev/sev

2. install libvirt and check domcapabilities output:

# virsh domcapabilities

    <sev supported='yes'>
      <cbitpos>47</cbitpos>
      <reducedPhysBits>1</reducedPhysBits>
    </sev>

3. start a guest with sev launchSecurity:

# virsh dumpxml vm1

  <launchSecurity type='sev'>
    <cbitpos>47</cbitpos>
    <reducedPhysBits>1</reducedPhysBits>
    <policy>0x0001</policy>
  </launchSecurity>

# virsh start vm1
Domain vm1 started

4. check /dev/sev device label:

# ll -Z /dev/sev 
crw-------. 1 root root system_u:object_r:sev_device_t:s0 10, 58 Feb  9 13:14 /dev/sev

5. set namespaces = [ ] in qemu.conf to disable guest mount namespace

6. restart libvirtd and start sev guest:

# virsh start vm1
error: Failed to start domain vm1
error: internal error: process exited while connecting to monitor: 2019-02-11T02:38:06.992512Z qemu-kvm: sev_guest_init: Failed to open /dev/sev 'Permission denied'
2019-02-11T02:38:06.995906Z qemu-kvm: failed to initialize KVM: Operation not permitted

7. check /dev/sev device label:

# ll -Z /dev/sev 
crw-------. 1 root root system_u:object_r:sev_device_t:s0 10, 58 Feb  9 13:14 /dev/sev

8. check domcapabilities output in non-root user:

$ virsh domcapabilities

<sev supported='no'/>