I've came across interesting bug recently. The problem was that
user tried to start a domain, but qemu was denied access to some
device. Even though we relabelled it initially. By debugging I
found the root cause: while we were starting qemu, udev came and
restored original security labels. Sigh. We have two options
here:
a) write out series of udev rules so that whenever it tries to
relabel something our rule will stop it from doing so
b) write a small helper binary that will udev call in order to:
1) detect whether device is in use by libvirt
2) get seclabel that was set by libvirt
These patches implement the latter approach. While these patches
make life easier for us, there is still a race when udev might
restore the device's seclabel before we had chance to flush
internal database of seclabels for the helper binary. This is
something I'm currently focusing on. But before I get there, here
are patches that makes the problem much more bearable.
In case you want to try these patches, here are some scratch builds:
https://mprivozn.fedorapeople.org/udev/
Also, you can find them on my branch:
https://github.com/zippy2/libvirt/commits/udev_labels2
This beast is turned off by default, to turn it on you'll need to add:
write_udev=1
to qemu.conf.
Michal Privoznik (17):
virseclabel.h: Include stdbool.h
virseclabel: Introduce virSecurityDeviceLabelDefNewLabel
security_dac: Pass manager to virSecurityDACSetImageLabel
security_dac: Pass manager to virSecurityDACRestoreFileLabelInternal
virudev: Introduce basic skeleton
virudev: Implement virUdevMgrAddLabel and virUdevMgrRemoveAllLabels
virudev: Introduce virUdevMgrDump
tests: Introduce virudevtest
virudev: Parse virUdevMgr from JSON
virudev: Introduce virUdevMgrLookupLabels
util: Introduce libvirt_udevhelper
security: Wire up virUdevMgr
qemu.conf: Introduce write_udev
qemu: Wire up virUdevMgr
qemu: Reload virUdevMgr on start
virudevtest: Introduce device filtering
qemu: Filter uninteresting paths for virUdevMgr
libvirt.spec.in | 1 +
mingw-libvirt.spec.in | 2 +
po/POTFILES.in | 2 +
src/Makefile.am | 21 ++
src/libvirt_private.syms | 15 +
src/qemu/libvirtd_qemu.aug | 1 +
src/qemu/qemu.conf | 5 +
src/qemu/qemu_conf.c | 3 +
src/qemu/qemu_conf.h | 5 +
src/qemu/qemu_domain.c | 12 +-
src/qemu/qemu_domain.h | 3 +-
src/qemu/qemu_driver.c | 40 +-
src/qemu/qemu_hotplug.c | 35 +-
src/qemu/qemu_process.c | 47 ++-
src/qemu/qemu_process.h | 3 +
src/qemu/test_libvirtd_qemu.aug.in | 1 +
src/security/security_dac.c | 103 ++++--
src/security/security_manager.c | 16 +
src/security/security_manager.h | 5 +
src/security/security_selinux.c | 47 ++-
src/util/udevhelper.c | 137 +++++++
src/util/virseclabel.c | 14 +
src/util/virseclabel.h | 6 +
src/util/virudev.c | 588 ++++++++++++++++++++++++++++++
src/util/virudev.h | 63 ++++
tests/Makefile.am | 12 +
tests/virudevmock.c | 29 ++
tests/virudevtest.c | 312 ++++++++++++++++
tests/virudevtestdata/complex.json | 30 ++
tests/virudevtestdata/empty.json | 5 +
tests/virudevtestdata/simple-dac.json | 13 +
tests/virudevtestdata/simple-selinux.json | 13 +
32 files changed, 1535 insertions(+), 54 deletions(-)
create mode 100644 src/util/udevhelper.c
create mode 100644 src/util/virudev.c
create mode 100644 src/util/virudev.h
create mode 100644 tests/virudevmock.c
create mode 100644 tests/virudevtest.c
create mode 100644 tests/virudevtestdata/complex.json
create mode 100644 tests/virudevtestdata/empty.json
create mode 100644 tests/virudevtestdata/simple-dac.json
create mode 100644 tests/virudevtestdata/simple-selinux.json
--
2.8.4