Using automated replacement with sed and editing I have now replaced all
occurrences of close() with VIR_(FORCE_)CLOSE() except for one, of
course. Some replacements were straight forward, others I needed to pay
attention. I hope I payed attention in all the right places... Please
have a look. This should have at least solved one more double-close
error.
NFS in root squash mode may prevent opening disk images to
determine backing store. Ignore errors in this scenario.
* src/security/security_selinux.c: Ignore open failures on disk
images
NFS does not support file labelling, so ignore this error
for stdin_path when on NFS.
* src/security/security_selinux.c: Ignore failures on labelling
stdin_path on NFS
* src/util/storage_file.c, src/util/storage_file.h: Refine
virStorageFileIsSharedFS() to allow it to check for a
specific FS type.
A more natural auditing point would perhaps be
SELinuxSetSecurityProcessLabel, but this happens in the child after root
permissions are dropped, so the kernel would refuse the audit record.
Description: Implement AppArmorSetSecurityHostdevLabel() and
AppArmorRestoreSecurityHostdevLabel() for hostdev and pcidev attach.
virt-aa-helper also has to be adjusted because *FileIterate() is used for pci
and usb devices and the corresponding XML for hot attached hostdev and pcidev
is not in the XML passed to virt-aa-helper. The new '-F filename' option is
added to append a rule to the profile as opposed to the existing '-f
filename', which rewrites the libvirt-<uuid>.files file anew. This new '-F'
option will append a rule to an existing libvirt-<uuid>.files if it exists,
otherwise it acts the same as '-f'.
load_profile() and reload_profile() have been adjusted to add an 'append'
argument, which when true will use '-F' instead of '-f' when executing
virt-aa-helper.
All existing calls to load_profile() and reload_profile() have been adjusted
to use the old behavior (ie append==false) except AppArmorSetSavedStateLabel()
where it made sense to use the new behavior.
This patch also adds tests for '-F'.
Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/libvirt/+bug/640993
Description: Check for VIR_DOMAIN_CHR_TYPE in serial ports and add 'rw' for
defined serial ports, parallel ports and channels
Bug-Ubuntu: LP: #578527, LP: #609055
Commit 68719c4bdd added the
p option to control disk format probing, but it wasn't added
to the getopt_long optstring parameter.
Add the p option to the getopt_long optstring parameter.
Commit a885334499 added this
function and wrapped vah_add_file in it. vah_add_file may
return -1, 0, 1. It returns 1 in case the call to valid_path
detects a restricted file. The original code treated a return
value != 0 as error. The refactored code treats a return
value < 0 as error. This triggers segfault in virt-aa-helper
and breaks virt-aa-helper-test for the restricted file tests.
Make sure that add_file_path returns -1 on error.
virt-aa-helper used to ignore errors when opening files.
Commit a885334499 refactored
the related code and changed this behavior. virt-aa-helper
didn't ignore open errors anymore and virt-aa-helper-test
fails.
Make sure that virt-aa-helper ignores open errors again.
Disk format probing is now disabled by default. A new config
option in /etc/qemu/qemu.conf will re-enable it for existing
deployments where this causes trouble
The implementation of security driver callbacks often needs
to access the security driver object. Currently only a handful
of callbacks include the driver object as a parameter. Later
patches require this is many more places.
* src/qemu/qemu_driver.c: Pass in the security driver object
to all callbacks
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_stacked.c,
src/security/security_apparmor.c, src/security/security_driver.h,
src/security/security_selinux.c: Add a virSecurityDriverPtr
param to all security callbacks
Update the QEMU cgroups code, QEMU DAC security driver, SELinux
and AppArmour security drivers over to use the shared helper API
virDomainDiskDefForeachPath().
* src/qemu/qemu_driver.c, src/qemu/qemu_security_dac.c,
src/security/security_selinux.c, src/security/virt-aa-helper.c:
Convert over to use virDomainDiskDefForeachPath()
Require the disk image to be passed into virStorageFileGetMetadata.
If this is set to VIR_STORAGE_FILE_AUTO, then the format will be
resolved using probing. This makes it easier to control when
probing will be used
* src/qemu/qemu_driver.c, src/qemu/qemu_security_dac.c,
src/security/security_selinux.c, src/security/virt-aa-helper.c:
Set VIR_STORAGE_FILE_AUTO when calling virStorageFileGetMetadata.
* src/storage/storage_backend_fs.c: Probe for disk format before
calling virStorageFileGetMetadata.
* src/util/storage_file.h, src/util/storage_file.c: Remove format
from virStorageFileMeta struct & require it to be passed into
method.
Also restore the label to its original value after qemu is finished
with the file.
Prior to this patch, qemu domain restore did not function properly if
selinux was set to enforce.
When configuring serial, parallel, console or channel devices
with a file, dev or pipe backend type, it is necessary to label
the file path in the security drivers. For char devices of type
file, it is neccessary to pre-create (touch) the file if it does
not already exist since QEMU won't be allowed todo so itself.
dev/pipe configs already require the admin to pre-create before
starting the guest.
* src/qemu/qemu_security_dac.c: set file ownership for character
devices
* src/security/security_selinux.c: Set file labeling for character
devices
* src/qemu/qemu_driver.c: Add character devices to cgroup ACL
The restore code is done in places where errors cannot be
raised, since they will overwrite over pre-existing errors.
* src/security/security_selinux.c: Only warn about failures
in label restore, don't report errors
When SELinux is running in MLS mode, libvirtd will have a
different security level to the VMs. For libvirtd to be
able to connect to the monitor console, the client end of
the UNIX domain socket needs a different label. This adds
infrastructure to set the socket label via the security
driver framework
* src/qemu/qemu_driver.c: Call out to socket label APIs in
security driver
* src/qemu/qemu_security_stacked.c: Wire up socket label
drivers
* src/security/security_driver.h: Define security driver
entry points for socket labelling
* src/security/security_selinux.c: Set socket label based on
VM label
Adjust args to qemudStartVMDaemon() to also specify path to stdin_fd,
so this can be passed to the AppArmor driver via SetSecurityAllLabel().
This updates all calls to qemudStartVMDaemon() as well as setting up
the non-AppArmor security driver *SetSecurityAllLabel() declarations
for the above. This is required for the following
"apparmor-fix-save-restore" patch since AppArmor resolves the passed
file descriptor to the pathname given to open().
Do not require each caller of virStorageFileGetMetadata and
virStorageFileGetMetadataFromFD to first clear the storage of the
"meta" buffer. Instead, initialize that storage in
virStorageFileGetMetadataFromFD.
* src/util/storage_file.c (virStorageFileGetMetadataFromFD): Clear
"meta" here, not before each of the following callers.
* src/qemu/qemu_driver.c (qemuSetupDiskCgroup): Don't clear "meta" here.
(qemuTeardownDiskCgroup): Likewise.
* src/qemu/qemu_security_dac.c (qemuSecurityDACSetSecurityImageLabel):
Likewise.
* src/security/security_selinux.c (SELinuxSetSecurityImageLabel):
Likewise.
* src/security/virt-aa-helper.c (get_files): Likewise.
virFileResolveLink was returning a positive value on error,
thus confusing callers that assumed failure was < 0. The
confusion is further evidenced by callers that would have
ended up calling virReportSystemError with a negative value
instead of a valid errno.
Fixes Red Hat BZ #591363.
* src/util/util.c (virFileResolveLink): Live up to documentation.
* src/qemu/qemu_security_dac.c
(qemuSecurityDACRestoreSecurityFileLabel): Adjust callers.
* src/security/security_selinux.c
(SELinuxRestoreSecurityFileLabel): Likewise.
* src/storage/storage_backend_disk.c
(virStorageBackendDiskDeleteVol): Likewise.
When QEMU runs with its disk on NFS, and as a non-root user, the
disk is chownd to that non-root user. When migration completes
the last step is shutting down the QEMU on the source host. THis
normally resets user/group/security label. This is bad when the
VM was just migrated because the file is still in use on the dest
host. It is thus neccessary to skip the reset step for any files
found to be on a shared filesystem
* src/libvirt_private.syms: Export virStorageFileIsSharedFS
* src/util/storage_file.c, src/util/storage_file.h: Add a new
method virStorageFileIsSharedFS() to determine if a file is
on a shared filesystem (NFS, GFS, OCFS2, etc)
* src/qemu/qemu_driver.c: Tell security driver not to reset
disk labels on migration completion
* src/qemu/qemu_security_dac.c, src/qemu/qemu_security_stacked.c,
src/security/security_selinux.c, src/security/security_driver.h,
src/security/security_apparmor.c: Add ability to skip disk
restore step for files on shared filesystems.
* src/security/virt-aa-helper.c: adjust virt-aa-helper to handle pci
devices. Update valid_path() to have an override array to check against,
and add "/sys/devices/pci" to it. Then rename file_iterate_cb() to
file_iterate_hostdev_cb() and create file_iterate_pci_cb() based on it
To avoid an error when hitting the <seclabel...> definition
* src/security/virt-aa-helper.c: add VIR_DOMAIN_XML_INACTIVE flag
to virDomainDefParseString
Don't exit with error if the user unloaded the profile outside of
libvirt
* src/security/virt-aa-helper.c: check the exit error from apparmor_parser
before exiting with a failure
The calls to virExec() in security_apparmor.c when
invoking virt-aa-helper use VIR_EXEC_CLEAR_CAPS. When compiled without
libcap-ng, this is not a problem (it's effectively a no-op) but with
libcap-ng this causes MAC_ADMIN to be cleared. MAC_ADMIN is needed by
virt-aa-helper to manipulate apparmor profiles and without it VMs will
not start[1]. This patch calls virExec with the default VIR_EXEC_NONE
instead.
* src/security/security_apparmor.c: fallback to VIR_EXEC_NONE flags for
virExec of virt_aa_helper
(suggested by Daniel Berrange, tested by Dan Kenigsberg)
virStorageFileGetMetadata will fail for disk images that are stored on
a root-squash NFS share that isn't world-readable.
SELinuxSetSecurityImageLabel is called during the startup of every
domain (as long as security_driver != "none"), and it will propogate
the error from virStorageFileGetMetadata, causing the domain startup
to fail. This is, however, a common scenario when qemu is run as a
non-root user and the disk image is stored on NFS.
Ignoring this failure (which doesn't matter in this case, since the
next thing done by SELinuxSetSecurityImageLabel - setting the file
context - will also fail (and that function already ignores failures
due to root-squash NFS) will allow us to continue bringing up the
domain. The result is that we don't need to disable the entire
security driver just because a domain's disk image is stored on
root-squashed NFS.
Changeset
commit 5073aa994a
Author: Cole Robinson <crobinso@redhat.com>
Date: Mon Jan 11 11:40:46 2010 -0500
Added support for product/vendor based passthrough, but it only
worked at the security driver layer. The main guest XML config
was not updated with the resolved bus/device ID. When the QEMU
argv refactoring removed use of product/vendor, this then broke
launching guests.
THe solution is to move the product/vendor resolution up a layer
into the QEMU driver. So the first thing QEMU does is resolve
the product/vendor to a bus/device and updates the XML config
with this info. The rest of the code, including security drivers
and QEMU argv generated can now rely on bus/device always being
set.
* src/util/hostusb.c, src/util/hostusb.h: Split vendor/product
resolution code out of usbGetDevice and into usbFindDevice.
Add accessors for bus/device ID
* src/security/virt-aa-helper.c, src/security/security_selinux.c,
src/qemu/qemu_security_dac.c: Remove vendor/product from the
usbGetDevice() calls
* src/qemu/qemu_driver.c: Use usbFindDevice to resolve vendor/product
into a bus/device ID
The virRaiseError macro inside of virSecurityReportError expands to
virRaiseErrorFull and includes the __FILE__, __FUNCTION__ and __LINE__
information. But this three values are always the same for every call
to virSecurityReportError and do not reflect the actual error context.
Converting virSecurityReportError into a macro results in getting the
correct __FILE__, __FUNCTION__ and __LINE__ information.
All callers now pass a NULL virConnectPtr into the USB/PCi device
iterator functions. Therefore the virConnectPtr arg can now be
removed from these functions
* src/util/hostusb.h, src/util/hostusb.c: Remove virConnectPtr
from usbDeviceFileIterate
* src/util/pci.c, src/util/pci.h: Remove virConnectPtr arg from
pciDeviceFileIterate
* src/qemu/qemu_security_dac.c, src/security/security_selinux.c: Update
to drop redundant virConnectPtr arg
The virConnectPtr is no longer required for error reporting since
that is recorded in a thread local. Remove use of virConnectPtr
from all APIs in security_driver.{h,c} and update all callers to
match
The current security driver architecture has the following
split of logic
* domainGenSecurityLabel
Allocate the unique label for the domain about to be started
* domainGetSecurityLabel
Retrieve the current live security label for a process
* domainSetSecurityLabel
Apply the previously allocated label to the current process
Setup all disk image / device labelling
* domainRestoreSecurityLabel
Restore the original disk image / device labelling.
Release the unique label for the domain
The 'domainSetSecurityLabel' method is special because it runs
in the context of the child process between the fork + exec.
This is require in order to set the process label. It is not
required in order to label disks/devices though. Having the
disk labelling code run in the child process limits what it
can do.
In particularly libvirtd would like to remember the current
disk image label, and only change shared image labels for the
first VM to start. This requires use & update of global state
in the libvirtd daemon, and thus cannot run in the child
process context.
The solution is to split domainSetSecurityLabel into two parts,
one applies process label, and the other handles disk image
labelling. At the same time domainRestoreSecurityLabel is
similarly split, just so that it matches the style. Thus the
previous 4 methods are replaced by the following 6 new methods
* domainGenSecurityLabel
Allocate the unique label for the domain about to be started
No actual change here.
* domainReleaseSecurityLabel
Release the unique label for the domain
* domainGetSecurityProcessLabel
Retrieve the current live security label for a process
Merely renamed for clarity.
* domainSetSecurityProcessLabel
Apply the previously allocated label to the current process
* domainRestoreSecurityAllLabel
Restore the original disk image / device labelling.
* domainSetSecurityAllLabel
Setup all disk image / device labelling
The SELinux and AppArmour drivers are then updated to comply with
this new spec. Notice that the AppArmour driver was actually a
little different. It was creating its profile for the disk image
and device labels in the 'domainGenSecurityLabel' method, where as
the SELinux driver did it in 'domainSetSecurityLabel'. With the
new method split, we can have consistency, with both drivers doing
that in the domainSetSecurityAllLabel method.
NB, the AppArmour changes here haven't been compiled so may not
build.
The QEMU driver is doing 90% of the calls to check for static vs
dynamic labelling. Except it is forgetting todo so in many places,
in particular hotplug is mistakenly assigning disk labels. Move
all this logic into the security drivers themselves, so the HV
drivers don't have to think about it.
* src/security/security_driver.h: Add virDomainObjPtr parameter
to virSecurityDomainRestoreHostdevLabel and to
virSecurityDomainRestoreSavedStateLabel
* src/security/security_selinux.c, src/security/security_apparmor.c:
Add explicit checks for VIR_DOMAIN_SECLABEL_STATIC and skip all
chcon() code in those cases
* src/qemu/qemu_driver.c: Remove all checks for VIR_DOMAIN_SECLABEL_STATIC
or VIR_DOMAIN_SECLABEL_DYNAMIC. Add missing checks for possibly NULL
driver entry points.
Based off how QEMU does it, look through /sys/bus/usb/devices/* for
matching vendor:product info, and if found, use info from the surrounding
files to build the device's /dev/bus/usb path.
This fixes USB device assignment by vendor:product when running qemu
as non-root (well, it should, but for some reason I couldn't reproduce
the failure people are seeing in [1], but it appears to work properly)
[1] https://bugzilla.redhat.com/show_bug.cgi?id=542450
Replace free(virBufferContentAndReset()) with virBufferFreeAndReset().
Update documentation and replace all remaining calls to free() with
calls to VIR_FREE(). Also add missing calls to virBufferFreeAndReset()
and virReportOOMError() in OOM error cases.
Introduce a new type="dir" mode for <disks> that allows use of
QEMU's virtual FAT block device driver. eg
<disk type='dir' device='floppy'>
<source dir='/tmp/test'/>
<target dev='fda' bus='fdc'/>
<readonly/>
</disk>
gets turned into
-drive file=fat:floppy:/tmp/test,if=floppy,index=0
Only read-only disks are supported with virtual FAT mode
* src/conf/domain_conf.c, src/conf/domain_conf.h: Add type="dir"
* docs/schemas/domain.rng: Document new disk type
* src/xen/xend_internal.c, src/xen/xm_internal.c: Raise error for
unsupported disk types
* tests/qemuxml2argvdata/qemuxml2argv-disk-cdrom-empty.args: Fix
empty disk file handling
* tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.args,
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-fat.xml,
tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.args,
tests/qemuxml2argvdata/qemuxml2argv-floppy-drive-fat.xml
tests/qemuxml2argvtest.c: Test QEMU vitual FAT driver
* src/qemu/qemu_conf.c: Support generating fat:/some/dir type
disk args
* src/security/security_selinux.c: Temporarily skip labelling
of directory based disks
Fixes https://launchpad.net/bugs/453335
* src/security/virt-aa-helper.c: suppress confusing and misleading
apparmor denied message when kvm/qemu tries to open a libvirt specified
readonly file (such as a cdrom) with write permissions. libvirt uses
the readonly attribute for the security driver only, and has no way
of telling kvm/qemu that the device should be opened readonly
Fixes https://launchpad.net/bugs/460271
* src/security/virt-aa-helper.c: require absolute path for dynamic added
files. This is required by AppArmor and conveniently prevents adding
tcp consoles to the profile
* src/security/virt-aa-helper.c: get_definition() now calls the new
caps_mockup() function which will parse the XML for os.type,
os.type.arch and then sets the wordsize. These attributes are needed
only to get a valid virCapsPtr for virDomainDefParseString(). The -H
and -b options are now removed from virt-aa-helper (they weren't used
yet anyway).
* tests/virt-aa-helper-test: extend and fixes tests, chmod'ed 755
When running qemu:///system instance, libvirtd runs as root,
but QEMU may optionally be configured to run non-root. When
then saving a guest to a state file, the file is initially
created as root, and thus QEMU cannot write to it. It is also
missing labelling required to allow access via SELinux.
* src/qemu/qemu_driver.c: Set ownership on save image before
running migrate command in virDomainSave impl. Call out to
security driver to set save image labelling
* src/security/security_driver.h: Add driver APIs for setting
and restoring saved state file labelling
* src/security/security_selinux.c: Implement saved state file
labelling for SELinux
- Don't duplicate SystemError
- Use proper error code in domain_conf
- Fix a broken error call in qemu_conf
- Don't use VIR_ERR_ERROR in security driver (isn't a valid code in this case)
Nearly all of the methods in src/util/util.h have error codes that
must be checked by the caller to correct detect & report failure.
Add ATTRIBUTE_RETURN_CHECK to ensure compile time validation of
this
* daemon/libvirtd.c: Add explicit check on return value of virAsprintf
* src/conf/domain_conf.c: Add missing check on virParseMacAddr return
value status & report error
* src/network/bridge_driver.c: Add missing OOM check on virAsprintf
and report error
* src/qemu/qemu_conf.c: Add missing check on virParseMacAddr return
value status & report error
* src/security/security_selinux.c: Remove call to virRandomInitialize
that's done in libvirt.c already
* src/storage/storage_backend_logical.c: Add check & log on virRun
return status
* src/util/util.c: Add missing checks on virAsprintf/Run status
* src/util/util.h: Annotate all methods with ATTRIBUTE_RETURN_CHECK
if they return an error status code
* src/vbox/vbox_tmpl.c: Add missing check on virParseMacAddr
* src/xen/xm_internal.c: Add missing checks on virAsprintf
* tests/qemuargv2xmltest.c: Remove bogus call to virRandomInitialize()
* configure.in: look for AppArmor and devel
* src/security/security_apparmor.[ch] src/security/security_driver.c
src/Makefile.am: add and plug the new driver
* src/security/virt-aa-helper.c: new binary which is used exclusively by
the AppArmor security driver to manipulate AppArmor.
* po/POTFILES.in: registers the new files
* tests/Makefile.am tests/secaatest.c tests/virt-aa-helper-test:
tests for virt-aa-helper and the security driver, secaatest.c is
identical to seclabeltest.c except it initializes the 'apparmor'
driver instead of 'selinux'
When James Morris originally submitted his sVirt patches (as seen in
libvirt 0.6.1), he did not require on disk labelling for
virSecurityDomainRestoreImageLabel. A later commit[2] changed this
behavior to assume on disk labelling, which halts implementations for
path-based MAC systems such as AppArmor and TOMOYO where
vm->def->seclabel is required to obtain the label.
* src/security/security_driver.h src/qemu/qemu_driver.c
src/security/security_selinux.c: adds the 'virDomainObjPtr vm'
argument back to *RestoreImageLabel
A simple misplaced break out of a switch results in:
libvir: error : Failed to open file '/sys/bus/pci/devices/0000:00:54c./vendor': No such file or directory
libvir: error : Failed to open file '/sys/bus/pci/devices/0000:00:54c./device': No such file or directory
libvir: error : this function is not supported by the hypervisor: Failed to read product/vendor ID for 0000:00:54c.
when trying to passthrough a USB host device to qemu.
* src/security_selinux.c: fix a switch/break thinko
Use virStorageFileGetMetadata() to find any backing stores for images
and re-label them
Without this, qemu cannot access qcow2 backing files, see:
https://bugzilla.redhat.com/497131
* src/security/security_selinux.c: re-label backing store files in
SELinuxSetSecurityImageLabel()