Libvirt doesn't care about security during hot add disk images. It even
accepts addition of disk images of other guest running on the host.
Steps followed to create this scenario :
Started two VMs with following security configurations:
vm1:
<seclabel type='dynamic' model='selinux' relabel='yes'>
<label>system_u:system_r:svirt_t:s0:c219,c564</label>
<imagelabel>system_u:object_r:svirt_image_t:s0:c219,c564</imagelabel>
</seclabel>
vm2 :
<seclabel type='dynamic' model='selinux' relabel='yes'>
<label>system_u:system_r:svirt_t:s0:c122,c658</label>
<imagelabel>system_u:object_r:svirt_image_t:s0:c122,c658</imagelabel>
</seclabel>
# virsh list --all
Id Name State
----------------------------------
28 vm1 running
29 vm2 running
# ls -lZ /var/lib/libvirt/images/
-rw-------. qemu qemu system_u:object_r:svirt_image_t:s0:c219,c564
vm1.img
-rw-------. qemu qemu system_u:object_r:svirt_image_t:s0:c122,c658
vm2.img
# ps auxZ | grep qemu-kvm | grep -v grep
system_u:system_r:svirt_t:s0:c219,c564 qemu 15744 47.2 5.8 2757852
472224 ? Sl 11:47 0:18 /usr/libexec/qemu-kvm -S -M rhel6.2.0
-enable-kvm -m 2048 -smp 4,sockets=4,cores=1,threads=1 -name vm1 -uuid
d3d3a3ee-4edf-a3d3-8dab-a77740266270 -nodefconfig -nodefaults -chardev
socket,id=charmonitor,path=/var/lib/libvirt/qemu/vm1.monitor,server,nowait -mon
chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown -drive
file=/var/lib/libvirt/images/vm1.img,if=none,id=drive-virtio-disk0,format=raw,cache=none
-device
virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1
-drive if=none,media=cdrom,id=drive-ide0-1-0,readonly=on,format=raw -device
ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 -netdev
tap,fd=26,id=hostnet0,vhost=on,vhostfd=27 -device
virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:a1:29:45,bus=pci.0,addr=0x3 -chardev
pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -usb -device
usb-tablet,id=input0 -vnc 127.0.0.1:0 -vga cirrus -device
intel-hda,id=sound0,bus=pci.0,addr=0x4 -device
hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 -device
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6
system_u:system_r:svirt_t:s0:c122,c658 qemu 15780 58.4 6.5 3063496
524048 ? Sl 11:47 0:20 /usr/libexec/qemu-kvm -S -M rhel6.2.0
-enable-kvm -m 2048 -smp 4,sockets=4,cores=1,threads=1 -name vm2 -uuid
b07607f8-2d03-cc1f-272b-22863667d1a4 -nodefconfig -nodefaults -chardev
socket,id=charmonitor,path=/var/lib/libvirt/qemu/vm2.monitor,server,nowait -mon
chardev=charmonitor,id=monitor,mode=control -rtc base=utc -no-shutdown -drive
file=/var/lib/libvirt/images/vm2.img,if=none,id=drive-virtio-disk0,format=raw,cache=none
-device
virtio-blk-pci,bus=pci.0,addr=0x5,drive=drive-virtio-disk0,id=virtio-disk0,bootindex=1
-drive if=none,media=cdrom,id=drive-ide0-1-0,readonly=on,format=raw -device
ide-drive,bus=ide.1,unit=0,drive=drive-ide0-1-0,id=ide0-1-0 -netdev
tap,fd=28,id=hostnet0,vhost=on,vhostfd=29 -device
virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:e0:76:d1,bus=pci.0,addr=0x3 -chardev
pty,id=charserial0 -device isa-serial,chardev=charserial0,id=serial0 -usb -device
usb-tablet,id=input0 -vnc 127.0.0.1:1 -vga cirrus -device
intel-hda,id=sound0,bus=pci.0,addr=0x4 -device
hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 -device
virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x6
Now, try to add vm1's disk image into vm2 - this must not be allowed -
since for virtualized guest images. Only svirt_t processes with the
same MCS fields can read/write these images. i.e., for vm2 to access
vm1's disk image it's MCS label must be 's0:c660,c689'.
Hot addition of vm1's image i.e., /var/lib/libvirt/images/vm1.img is
successful ( which must not be allowed )
moreover , MCS label for vm1's image has changed to that of vm2
# ls -lZ /var/lib/libvirt/images/
-rw-------. qemu qemu system_u:object_r:svirt_image_t:s0:c122,c658
vm1.img
-rw-------. qemu qemu system_u:object_r:svirt_image_t:s0:c122,c658
vm2.img
Trying to read/write on vm1 will generate AVC messages
Seen following message in /var/log/audit/audit.log :
type=VIRT_RESOURCE msg=audit(1332310867.790:10312): user pid=5114 uid=0
auid=0 ses=3 subj=unconfined_u:system_r:virtd_t:s0-s0:c0.c1023
msg='virt=kvm resrc=disk reason=attach vm="vm2"
uuid=b07607f8-2d03-cc1f-272b-22863667d1a4 old-disk="?"
new-disk="/var/lib/libvirt/images/vm1.img":
exe=2F7573722F7362696E2F6C69627669727464202864656C6574656429 hostname=?
addr=? terminal=? res=success'
type=AVC msg=audit(1332310963.333:10313): avc: denied { write } for
pid=16241 comm="qemu-kvm" path="/var/lib/libvirt/images/vm1.img"
dev=sda1 ino=6431944 scontext=system_u:system_r:svirt_t:s0:c219,c564
tcontext=system_u:object_r:svirt_image_t:s0:c122,c658 tclass=file
type=SYSCALL msg=audit(1332310963.333:10313): arch=c000003e syscall=18
success=no exit=-13 a0=9 a1=7fd3bc59d000 a2=1000 a3=10891b000 items=0
ppid=1 pid=16241 auid=0 uid=107 gid=107 euid=107 suid=107 fsuid=107
egid=107 sgid=107 fsgid=107 tty=(none) ses=3 comm="qemu-kvm"
exe="/usr/libexec/qemu-kvm" subj=system_u:system_r:svirt_t:s0:c219,c564
key=(null)
type=AVC msg=audit(1332310963.337:10314): avc: denied { read } for
pid=16241 comm="qemu-kvm" path="/var/lib/libvirt/images/vm1.img"
dev=sda1 ino=6431944 scontext=system_u:system_r:svirt_t:s0:c219,c564
tcontext=system_u:object_r:svirt_image_t:s0:c122,c658 tclass=file
type=SYSCALL msg=audit(1332310963.337:10314): arch=c000003e syscall=295
success=no exit=-13 a0=9 a1=2d24368 a2=4 a3=88664000 items=0 ppid=1
pid=16241 auid=0 uid=107 gid=107 euid=107 suid=107 fsuid=107 egid=107
sgid=107 fsgid=107 tty=(none) ses=3 comm="qemu-kvm"
exe="/usr/libexec/qemu-kvm" subj=system_u:system_r:svirt_t:s0:c219,c564
key=(null)
type=AVC msg=audit(1332310963.338:10315): avc: denied { read } for
pid=16241 comm="qemu-kvm" path="/var/lib/libvirt/images/vm1.img"
dev=sda1 ino=6431944 scontext=system_u:system_r:svirt_t:s0:c219,c564
tcontext=system_u:object_r:svirt_image_t:s0:c122,c658 tclass=file
type=SYSCALL msg=audit(1332310963.338:10315): arch=c000003e syscall=17
success=no exit=-13 a0=9 a1=7fd3bce4f000 a2=1000 a3=88664000 items=0
ppid=1 pid=16241 auid=0 uid=107 gid=107 euid=107 suid=107 fsuid=107
egid=107 sgid=107 fsgid=107 tty=(none) ses=3 comm="qemu-kvm"
exe="/usr/libexec/qemu-kvm" subj=system_u:system_r:svirt_t:s0:c219,c564
key=(null)
type=AVC msg=audit(1332310967.954:10316): avc: denied { read } for
pid=16241 comm="qemu-kvm" path="/var/lib/libvirt/images/vm1.img"
dev=sda1 ino=6431944 scontext=system_u:system_r:svirt_t:s0:c219,c564
tcontext=system_u:object_r:svirt_image_t:s0:c122,c658 tclass=file
type=SYSCALL msg=audit(1332310967.954:10316): arch=c000003e syscall=295
success=no exit=-13 a0=9 a1=2d43768 a2=3 a3=1907c8000 items=0 ppid=1
pid=16241 auid=0 uid=107 gid=107 euid=107 suid=107 fsuid=107 egid=107
sgid=107 fsgid=107 tty=(none) ses=3 comm="qemu-kvm"
exe="/usr/libexec/qemu-kvm" subj=system_u:system_r:svirt_t:s0:c219,c564
key=(null)
type=AVC msg=audit(1332310967.955:10317): avc: denied { read } for
pid=16241 comm="qemu-kvm" path="/var/lib/libvirt/images/vm1.img"
dev=sda1 ino=6431944 scontext=system_u:system_r:svirt_t:s0:c219,c564
tcontext=system_u:object_r:svirt_image_t:s0:c122,c658 tclass=file
type=SYSCALL msg=audit(1332310967.955:10317): arch=c000003e syscall=17
success=no exit=-13 a0=9 a1=7fd3bac95000 a2=1000 a3=1907c8000 items=0
ppid=1 pid=16241 auid=0 uid=107 gid=107 euid=107 suid=107 fsuid=107
egid=107 sgid=107 fsgid=107 tty=(none) ses=3 comm="qemu-kvm"
exe="/usr/libexec/qemu-kvm" subj=system_u:system_r:svirt_t:s0:c219,c564
key=(null)
type=AVC msg=audit(1332310968.594:10318): avc: denied { write } for
pid=16241 comm="qemu-kvm" path="/var/lib/libvirt/images/vm1.img"
dev=sda1 ino=6431944 scontext=system_u:system_r:svirt_t:s0:c219,c564
tcontext=system_u:object_r:svirt_image_t:s0:c122,c658 tclass=file
type=SYSCALL msg=audit(1332310968.594:10318): arch=c000003e syscall=18
success=no exit=-13 a0=9 a1=7fd3bded9000 a2=1000 a3=2c3f000 items=0
ppid=1 pid=16241 auid=0 uid=107 gid=107 euid=107 suid=107 fsuid=107
egid=107 sgid=107 fsgid=107 tty=(none) ses=3 comm="qemu-kvm"
exe="/usr/libexec/qemu-kvm" subj=system_u:system_r:svirt_t:s0:c219,c564
key=(null)
type=AVC msg=audit(1332310968.594:10319): avc: denied { write } for
pid=16241 comm="qemu-kvm" path="/var/lib/libvirt/images/vm1.img"
dev=sda1 ino=6431944 scontext=system_u:system_r:svirt_t:s0:c219,c564
tcontext=system_u:object_r:svirt_image_t:s0:c122,c658 tclass=file
type=SYSCALL msg=audit(1332310968.594:10319): arch=c000003e syscall=18
success=no exit=-13 a0=9 a1=7fd3b7947000 a2=1000 a3=9db2d000 items=0
ppid=1 pid=16241 auid=0 uid=107 gid=107 euid=107 suid=107 fsuid=107
egid=107 sgid=107 fsgid=107 tty=(none) ses=3 comm="qemu-kvm"
exe="/usr/libexec/qemu-kvm" subj=system_u:system_r:svirt_t:s0:c219,c564
key=(null)
type=AVC msg=audit(1332310968.594:10320): avc: denied { write } for
pid=16241 comm="qemu-kvm" path="/var/lib/libvirt/images/vm1.img"
dev=sda1 ino=6431944 scontext=system_u:system_r:svirt_t:s0:c219,c564
tcontext=system_u:object_r:svirt_image_t:s0:c122,c658 tclass=file
type=SYSCALL msg=audit(1332310968.594:10320): arch=c000003e syscall=296
success=no exit=-13 a0=9 a1=2d6c0f8 a2=b a3=18851e000 items=0 ppid=1
pid=16241 auid=0 uid=107 gid=107 euid=107 suid=107 fsuid=107 egid=107
sgid=107 fsgid=107 tty=(none) ses=3 comm="qemu-kvm"
exe="/usr/libexec/qemu-kvm" subj=system_u:system_r:svirt_t:s0:c219,c564
key=(null)
type=AVC msg=audit(1332310968.598:10321): avc: denied { write } for
pid=16241 comm="qemu-kvm" path="/var/lib/libvirt/images/vm1.img"
dev=sda1 ino=6431944 scontext=system_u:system_r:svirt_t:s0:c219,c564
tcontext=system_u:object_r:svirt_image_t:s0:c122,c658 tclass=file
type=SYSCALL msg=audit(1332310968.598:10321): arch=c000003e syscall=18
success=no exit=-13 a0=9 a1=7fd383b0f000 a2=1000 a3=18842e000 items=0
ppid=1 pid=16241 auid=0 uid=107 gid=107 euid=107 suid=107 fsuid=107
egid=107 sgid=107 fsgid=107 tty=(none) ses=3 comm="qemu-kvm"
exe="/usr/libexec/qemu-kvm" subj=system_u:system_r:svirt_t:s0:c219,c564
key=(null)
restricting vm1 read/write it's own image.
Changing seclabels with virsh/virt-manager is not supported so defined a
new XML with
<seclabel type='dynamic' model='selinux' relabel='no'>
<label>system_u:system_r:svirt_t:s0:c110,c401</label>
<imagelabel>system_u:object_r:svirt_image_t:s0:c110,c401</imagelabel>
</seclabel>
but when I try to define it , gives me error :
# virsh define vm3.xml
error: Failed to define domain from vm3.xml
error: unsupported configuration: dynamic label type must use resource
relabeling
looks like it's not possible to assign relabel='no' with dynamic
labelling.
libvirt/src/conf/domain_conf.c :
if (def->type == VIR_DOMAIN_SECLABEL_DYNAMIC &&
def->norelabel) {
virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
"%s", _("dynamic label type must use
resource relabeling"));
goto error;
}
--
Onkar N Mahajan
System Software Engineer,
IBM Linux Technology Center,
Bangalore,India