Bug 657252

Summary: Change the media in an existing CDROM device on the fly for a guest failed with svirt
Product: Red Hat Enterprise Linux 5 Reporter: Min Zhan <mzhan>
Component: selinux-policyAssignee: Miroslav Grepl <mgrepl>
Status: CLOSED DUPLICATE QA Contact: BaseOS QE Security Team <qe-baseos-security>
Severity: medium Docs Contact:
Priority: high    
Version: 5.6CC: berrange, dwalsh, dyuan, gcosta, jdenemar, ksrot, llim, michen, mkenneth, mmalik, mshao, mzhan, virt-maint
Target Milestone: rcKeywords: Reopened, Triaged
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2011-05-19 15:34:45 UTC Type: ---
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: 580948    
Attachments:
Description Flags
block: read-only: open cdrom as read-only when using monitor's change command
none
mount issue none

Description Min Zhan 2010-11-25 10:23:46 UTC
Description of problem:
In Enforcing mode, guest with an existing cdrom device start successfully. But update the media on the fly, then error display

Version-Release number of selected component (if applicable):
RHEL5.6-Server-kvm-x86_64
kernel-2.6.18-233.el5
kvm-83-215.el5
libvirt-0.8.2-14.el5
selinux-policy-2.4.6-293.el5

How reproducible:
Always

Steps to Reproduce:
1.# getenforce
Enforcing

2.Prepare 2 different ISO files.
# mkisofs -o /var/lib/libvirt/image/tmp1.iso /tmp

Do some changes in /tmp directory, such as, add/change/remove some new file to make a different iso file

# mkisofs -o /var/lib/libvirt/image/tmp2.iso /tmp
3.Adding the following to the guest xml
......

    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/var/lib/libvirt/images/tmp1.iso'/>
      <target dev='hdc' bus='ide'/>
      <readonly/>
    </disk>
.......

4.Prepare a xml as following:

# cat cdrom.xml
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/var/lib/libvirt/images/tmp2.iso'/>
      <target dev='hdc' bus='ide'/>
      <readonly/>
    </disk>
  
5.# virsh start <guest>
6.In guest, mount the cdrom device, and check the media's context.Then umount.
7.# virsh update-device <guest> cdrom.xml

Actual results:
# virsh update-device i386 cdrom.xml
error: Failed to update device from cdrom.xml
error: operation failed: could not change media on ide1-cd0: Could not open '/var/lib/libvirt/images/tmp2.iso'

# ll -lhs /var/lib/libvirt/images/
392K -rw-r--r-- 1 root root 384K Nov 25 17:40 tmp1.iso
396K -rw-r--r-- 1 root root 388K Nov 25 17:40 tmp2.iso

Expected results:
Device can be updated successfully

Additional info:

# tail -f /var/log/libvirt/qemu/i386.log
LC_ALL=C PATH=/sbin:/usr/sbin:/bin:/usr/bin QEMU_AUDIO_DRV=none /usr/libexec/qemu-kvm -S -M rhel5.4.0 -m 512 -smp 2,sockets=2,cores=1,threads=1 -name i386 -uuid ebe14da0-b28c-05bf-31ab-9e583ff47e0b -monitor unix:/var/lib/libvirt/qemu/i386.monitor,server,nowait -no-kvm-pit-reinjection -boot c -drive file=/var/lib/libvirt/images/i386.img,if=virtio,boot=on,format=raw,cache=none -drive file=/var/lib/libvirt/images/tmp1.iso,if=ide,media=cdrom,bus=1,unit=0,readonly=on,format=raw -net nic,macaddr=54:52:00:15:c1:66,vlan=0,model=virtio -net tap,fd=23,vlan=0 -serial file:/var/log/vm-serial.log -parallel none -usb -vnc 127.0.0.1:1 -k en-us -vga cirrus -soundhw ac97 -balloon virtio 

# tail -f /var/log/messages 
Nov 25 18:20:51 dhcp-65-85 libvirtd: 18:20:51.274: error : qemuMonitorTextChangeMedia:1051 : operation failed: could not change media on ide1-cd0: Could not open '/var/lib/libvirt/images/tmp2.iso'

# tail -f /var/log/audit/audit.log 
type=VIRT_RESOURCE msg=audit(1290680451.275:415): user pid=10666 uid=0 auid=0 subj=root:system_r:virtd_t:s0-s0:c0.c1023 msg='resrc=disk reason=update vm="i386" uuid=ebe14da0-b28c-05bf-31ab-9e583ff47e0b old-disk="/var/lib/libvirt/images/tmp1.iso" new-disk="/var/lib/libvirt/images/tmp2.iso": exe="/usr/sbin/libvirtd" (hostname=?, addr=?, terminal=? res=failed)'

Comment 1 Miroslav Grepl 2010-11-25 13:08:49 UTC
Please re-test it and add some outputs:

# ls -lZ /var/lib/libvirt/images/
# ausearch -m avc -ts recent

I believe it is a problem with labeling.

Comment 2 Min Zhan 2010-11-26 08:18:16 UTC
(In reply to comment #1)

# ll -lZ /var/lib/libvirt/images/
-rw-r--r--  root root system_u:object_r:virt_content_t tmp1.iso
-rw-r--r--  root root system_u:object_r:virt_content_t tmp2.iso


# ausearch -m avc -ts recent
<no matches>

Comment 4 Miroslav Grepl 2010-11-29 11:00:26 UTC
(In reply to comment #1)
> Please re-test it and add some outputs:
> 
> # ls -lZ /var/lib/libvirt/images/
> # ausearch -m avc -ts recent
> 
> I believe it is a problem with labeling.

Please test it in permissive mode. Thanks.

# setenforce 0

Re-test and check AVC messages using ausearch.

Comment 5 Min Zhan 2010-11-30 09:43:09 UTC
(In reply to comment #4)

I re-test it in permissive mode. But the results are the same with Comment 2.

# getenforce 
Permissive

# ll -lZ /var/lib/libvirt/images/
-rw-r--r--  root root system_u:object_r:virt_content_t tmp1.iso
-rw-r--r--  root root system_u:object_r:virt_content_t tmp2.iso

# ausearch -m avc -ts recent
<no matches>

Comment 6 Miroslav Grepl 2010-11-30 11:46:05 UTC
Does it work in permissive mode?

Comment 7 Min Zhan 2010-12-01 02:34:44 UTC
(In reply to comment #6)

It works well in permissive mode.That means if

# setenforce 0
# virsh update-device <guest> cdrom.xml
update successfully

Comment 8 Miroslav Grepl 2010-12-01 09:07:11 UTC
Ok, just turn of dontaudit rules using

# semodule -DB

and also restart auditd daemon

# service auditd restart

Now please repeat the test.

Comment 9 Miroslav Grepl 2010-12-01 09:15:36 UTC
Also please use the latest selinux-policy (-296 release). There is a bug in -293 release which could cause it does not work.

Comment 11 Min Zhan 2010-12-03 08:39:09 UTC
(In reply to comment #9)

Re-test in selinux-policy-296 release in enforcing mode, the same error message will display.

# getenforce
Enforcing

# virsh update-device test cdrom.xml 
error: Failed to update device from cdrom.xml
error: operation failed: could not change media on ide1-cd0: Could not open '/var/lib/libvirt/images/tmp2.iso'

# ll -lZ /var/lib/libvirt/images/
-rw-r--r--  root root system_u:object_r:virt_content_t tmp1.iso
-rw-r--r--  root root system_u:object_r:virt_content_t tmp2.iso

# ausearch -m avc -ts recent
----
time->Fri Dec  3 16:36:08 2010
type=SYSCALL msg=audit(1291365368.585:35): arch=c000003e syscall=59 success=yes exit=0 a0=2b3366c4de80 a1=2b336a84da70 a2=0 a3=0 items=0 ppid=4393 pid=4394 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts1 ses=1 comm="load_policy" exe="/usr/sbin/load_policy" subj=root:system_r:load_policy_t:s0-s0:c0.c1023 key=(null)
type=AVC msg=audit(1291365368.585:35): avc:  denied  { noatsecure } for  pid=4394 comm="load_policy" scontext=root:system_r:semanage_t:s0-s0:c0.c1023 tcontext=root:system_r:load_policy_t:s0-s0:c0.c1023 tclass=process
type=AVC msg=audit(1291365368.585:35): avc:  denied  { rlimitinh } for  pid=4394 comm="load_policy" scontext=root:system_r:semanage_t:s0-s0:c0.c1023 tcontext=root:system_r:load_policy_t:s0-s0:c0.c1023 tclass=process
type=AVC msg=audit(1291365368.585:35): avc:  denied  { siginh } for  pid=4394 comm="load_policy" scontext=root:system_r:semanage_t:s0-s0:c0.c1023 tcontext=root:system_r:load_policy_t:s0-s0:c0.c1023 tclass=process

Comment 12 Miroslav Grepl 2010-12-03 10:20:59 UTC
(In reply to comment #11)
> (In reply to comment #9)
> 
> Re-test in selinux-policy-296 release in enforcing mode, the same error message
> will display.
> 
> # getenforce
> Enforcing

And any chance you get more AVC messages in permissive mode?

Also could you attach your compressed /var/log/audit/audit.log file.

Comment 13 Miroslav Grepl 2010-12-05 21:38:49 UTC
Ok, 
this issue ends up with the following AVC message

type=SYSCALL msg=audit(1291586560.290:56144): arch=c000003e syscall=2 success=no exit=-13 a0=2d5f600 a1=81002 a2=0 a3=40 items=1 ppid=1 pid=32292 auid=4294967295 uid=107 gid=107 euid=107 suid=107 fsuid=107 egid=107 sgid=107 fsgid=107 tty=(none) ses=4294967295 comm="qemu-kvm" exe="/usr/bin/qemu-kvm" subj=system_u:system_r:svirt_t:s0:c569,c812 key=(null)
type=AVC msg=audit(1291586560.290:56144): avc:  denied  { write } for  pid=32292 comm="qemu-kvm" name="tmp2.iso" dev=dm-0 ino=2492610 scontext=system_u:system_r:svirt_t:s0:c569,c812 tcontext=system_u:object_r:virt_content_t:s0 tclass=file

So

#============= svirt_t ==============
allow svirt_t virt_content_t:file write;

which is not allowed.

Comment 14 Miroslav Grepl 2010-12-06 08:44:42 UTC
Virt guys.
could you look at this?

Comment 15 Daniel Berrangé 2010-12-06 17:15:21 UTC
This is a QEMU bug. In the impl of the 'change' command in RHEL5 it always tries to open read-write.

static void do_change_block(const char *device, const char *filename, const char *fmt)
{
  ...
    if (bdrv_open2(bs, filename, BDRV_O_RDWR, drv) != 0) {
  ...
}


In RHEL6 it only tries to open readonly for CDROMs

    bdrv_flags = bdrv_get_type_hint(bs) == BDRV_TYPE_CDROM ? 0 : BDRV_O_RDWR;
    if (bdrv_open(bs, filename, bdrv_flags, drv)) {

The patch from RHEL6 QEMU was

  kvm-block-read-only-open-cdrom-as-read-only-when-using-m.patch
  Upstream commit: cb4e5f8ed1b648c451491b10dc92b1af1e324535
  BZ: 602026

Comment 16 Miroslav Grepl 2010-12-06 17:23:51 UTC
You are right. Afaik there was the same bug also in Fedora.

Thanks.

Comment 19 Markus Armbruster 2011-01-17 14:56:50 UTC
This could be a duplicate of bug 586173.  Christoph, what do you think?  If it isn't, feel free to assign back to me.

Comment 20 chellwig@redhat.com 2011-01-17 15:11:54 UTC
It most likely is.  But I don't want to mark it as duplicate before I have the patch to test it.

Comment 21 chellwig@redhat.com 2011-01-17 15:19:39 UTC
Created attachment 473859 [details]
block: read-only: open cdrom as read-only when using monitor's change command

Can you please check if the following patch fixes it?  It's a backport from qemu mainline thas has already landed in RHEL6 as well.

Comment 22 chellwig@redhat.com 2011-03-18 10:43:17 UTC
Can you please verify that your issue is fixed with the newest qemu-kvm rpm?

Comment 23 Min Zhan 2011-03-21 06:59:00 UTC
(In reply to comment #22)

Re-test in enforcing mode and found the result is still failed.

# virsh update-device new cdrom.xml 
error: Failed to update device from cdrom.xml
error: operation failed: could not change media on ide1-cd0: Could not open '/var/lib/libvirt/images/tmp2.iso'

# ausearch -m avc -ts recent
...
time->Mon Mar 21 23:07:00 2011
type=SYSCALL msg=audit(1300720020.854:104): arch=c000003e syscall=2 success=no exit=-13 a0=303dc12a64 a1=0 a2=1b6 a3=0 items=0 ppid=3547 pid=5031 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=4294967295 comm="qemu-kvm" exe="/usr/libexec/qemu-kvm" subj=system_u:system_r:qemu_t:s0-s0:c0.c1023 key=(null)
type=AVC msg=audit(1300720020.854:104): avc:  denied  { read } for  pid=5031 comm="qemu-kvm" name="config" dev=sda3 ino=2491881 scontext=system_u:system_r:qemu_t:s0-s0:c0.c1023 tcontext=system_u:object_r:selinux_config_t:s0 tclass=file


Environment:
# uname -a
Linux localhost.localdomain 2.6.18-237.el5 #1 SMP Mon Dec 13 18:07:57 EST 2010 x86_64 x86_64 x86_64 GNU/Linux
kvm-83-224.el5
libvirt-0.8.2-15.el5
selinux-policy-2.4.6-300.el5

Comment 24 chellwig@redhat.com 2011-03-21 10:20:52 UTC
There's not much I can do if the combination of selinux and libvirt's braindead configuration of it prevents you from reopening a CDROM, as it's outside of qemu's control at this point.  Given that it works with a sane qemu config please open a new bug against libvirt for that issue.

Comment 25 Daniel Berrangé 2011-03-21 10:51:35 UTC
> type=AVC msg=audit(1300720020.854:104): avc:  denied  { read } for  pid=5031
> comm="qemu-kvm" name="config" dev=sda3 ino=2491881
> scontext=system_u:system_r:qemu_t:s0-s0:c0.c1023
> tcontext=system_u:object_r:selinux_config_t:s0 tclass=file

That audit log message does not appear to be related to opening of the '/var/lib/libvirt/images/tmp2.iso' file. The I'm guessing  selinux_config_t may well be one of the SELinux policy files itself, probably  the file /etc/selinux/config. Perhaps Miloslav can confirm, but I'd suggest triggering a complete re-label of the entire filesystem.

  touch /.autorelabel

and then reboot the host, and once relabelling completes, repeat your testing of KVM/libvirt again.

Comment 26 Min Zhan 2011-03-29 08:02:55 UTC
Re-test on below environment:
# uname -a
Linux localhost.localdomain 2.6.18-237.el5 #1 SMP Mon Dec 13 18:07:57 EST 2010
x86_64 x86_64 x86_64 GNU/Linux
kvm-83-225.el5
libvirt-0.8.2-15.el5
selinux-policy-2.4.6-300.el5

Steps:
1. # getenforce
  Enforcing

2. # virsh dumpxml new
...
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <source file='/var/lib/libvirt/images/tmp1.iso'/>
      <target dev='hdc' bus='ide'/>
      <readonly/>
      <alias name='ide1-cd0'/>
      <address type='drive' controller='0' bus='1' unit='0'/>
    </disk>
...

# virsh start new
Domain new started

In guest, mount this cdrom and check, then umount.

3. Prepare the cdrom xml
# cat cdrom.xml 
  <disk type='file' device='cdrom'>
     <driver name='file'/>
      <source file='/var/lib/libvirt/images/tmp2.iso'/>
      <target dev='hdc' bus='ide'/>
      <readonly/>
    </disk>

4. update device on the fly
# virsh update-device new cdrom.xml 
Device updated successfully

# ausearch -m avc -ts recent
time->Wed Mar 30 00:07:46 2011
type=SYSCALL msg=audit(1301414866.114:639): arch=c000003e syscall=2 success=no exit=-13 a0=303dc12a64 a1=0 a2=1b6 a3=0 items=0 ppid=4594 pid=5187 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) ses=1 comm="qemu-kvm" exe="/usr/libexec/qemu-kvm" subj=root:system_r:qemu_t:s0-s0:c0.c1023 key=(null)
type=AVC msg=audit(1301414866.114:639): avc:  denied  { read } for  pid=5187 comm="qemu-kvm" name="config" dev=sda3 ino=2491881 scontext=root:system_r:qemu_t:s0-s0:c0.c1023 tcontext=system_u:object_r:selinux_config_t:s0 tclass=file

5. But In guest, mount tmp2.iso cdrom, some error will display for the first time mount. Please refer to the attachment. Please help to confirm, thanks

Comment 27 Min Zhan 2011-03-29 08:05:34 UTC
Created attachment 488366 [details]
mount issue

Comment 28 Daniel Walsh 2011-03-29 18:18:10 UTC
Could you turn off
allow_unconfined_qemu_transition 
And stop running qemu_t in a confined way.

# setsebool -P allow_unconfined_qemu_transition 0
 
Should remove this SELinux protection.

I have no idea why qemu would be trying to read /etc/selinux/config.

Comment 29 Min Zhan 2011-03-30 05:36:54 UTC
(In reply to comment #28)

I have tried to turn off allow_unconfined_qemu_transition,but seems it is not existed in database. 

# getenforce
Enforcing

# setsebool -P allow_unconfined_qemu_transition 0
libsemanage.dbase_llist_set: record not found in the database
libsemanage.dbase_llist_set: could not set record value
Could not change boolean allow_unconfined_qemu_transition
Could not change policy booleans

Also Re-test, the test result is the same as Comment #26.

Comment 30 Daniel Walsh 2011-03-30 19:50:48 UTC
I think this is a testsuite that is transitioning to qemu_t rather then svirt_t?

Comment 48 Miroslav Grepl 2011-05-19 08:45:37 UTC
Milos, Karel,
could you also try to test this?

Comment 55 Miroslav Grepl 2011-05-19 15:34:45 UTC

*** This bug has been marked as a duplicate of bug 586173 ***