xorl %eax, %eax

CVE-2011-1146: LibVirt API Routines Missing Checks

leave a comment »

This is a vulnerability due to missing status checks on some API routines. These are:

– virConnectDomainXMLToNative()
– virNodeDeviceDettach()
– virNodeDeviceReAttach()
– virNodeDeviceReset()
– virDomainRevertToSnapshot()
– virDomainSnapshotDelete()

All of these routines are part of src/libvirt.c file which contains the “main interfaces for the libvirt library to handle virtualization domains from a process running in domain 0” as the code comments say.

From the code documentation here is a quick overview of each of the above routines:

– virConnectDomainXMLToNative()

/**
 * virConnectDomainXMLToNative:
 * @conn: a connection object
 * @nativeFormat: configuration format exporting to
 * @domainXml: the domain configuration to export
 * @flags: currently unused, pass 0
 *
 * Reads a domain XML configuration document, and generates
 * a native configuration file describing the domain.
 * The format of the native data is hypervisor dependant.
 *
 * Returns a 0 terminated UTF-8 encoded native config datafile, or NULL in case of error.
 *         the caller must free() the returned value.
 */
char *virConnectDomainXMLToNative(virConnectPtr conn,
                                  const char *nativeFormat,
                                  const char *domainXml,
                                  unsigned int flags)

– virNodeDeviceDettach()

/**
 * virNodeDeviceDettach:
 * @dev: pointer to the node device
 *
 * Dettach the node device from the node itself so that it may be
 * assigned to a guest domain.
 *
 * Depending on the hypervisor, this may involve operations such
 * as unbinding any device drivers from the device, binding the
 * device to a dummy device driver and resetting the device.
 *
 * If the device is currently in use by the node, this method may
 * fail.
 *
 * Once the device is not assigned to any guest, it may be re-attached
 * to the node using the virNodeDeviceReattach() method.
 *
 * Returns 0 in case of success, -1 in case of failure.
 */
int
virNodeDeviceDettach(virNodeDevicePtr dev)

– virNodeDeviceReAttach()

/**
 * virNodeDeviceReAttach:
 * @dev: pointer to the node device
 *
 * Re-attach a previously dettached node device to the node so that it
 * may be used by the node again.
 *
 * Depending on the hypervisor, this may involve operations such
 * as resetting the device, unbinding it from a dummy device driver
 * and binding it to its appropriate driver.
 *
 * If the device is currently in use by a guest, this method may fail.
 *
 * Returns 0 in case of success, -1 in case of failure.
 */
int
virNodeDeviceReAttach(virNodeDevicePtr dev)

– virNodeDeviceReset()

/**
 * virNodeDeviceReset:
 * @dev: pointer to the node device
 *
 * Reset a previously dettached node device to the node before or
 * after assigning it to a guest.
 *
 * The exact reset semantics depends on the hypervisor and device
 * type but, for example, KVM will attempt to reset PCI devices with
 * a Function Level Reset, Secondary Bus Reset or a Power Management
 * D-State reset.
 *
 * If the reset will affect other devices which are currently in use,
 * this function may fail.
 *
 * Returns 0 in case of success, -1 in case of failure.
 */
int
virNodeDeviceReset(virNodeDevicePtr dev)

– virDomainRevertToSnapshot()

/**
 * virDomainRevertToSnapshot:
 * @snapshot: a domain snapshot object
 * @flags: unused flag parameters; callers should pass 0
 *
 * Revert the domain to a given snapshot.
 *
 * Returns 0 if the creation is successful, -1 on error.
 */
int
virDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
                          unsigned int flags)

– virDomainSnapshotDelete()

/**
 * virDomainSnapshotDelete:
 * @snapshot: a domain snapshot object
 * @flags: flag parameters
 *
 * Delete the snapshot.
 *
 * If @flags is 0, then just this snapshot is deleted, and changes from
 * this snapshot are automatically merged into children snapshots.  If
 * flags is VIR_DOMAIN_SNAPSHOT_DELETE_CHILDREN, then this snapshot
 * and any children snapshots are deleted.
 *
 * Returns 0 if the snapshot was successfully deleted, -1 on error.
 */
int
virDomainSnapshotDelete(virDomainSnapshotPtr snapshot,
                        unsigned int flags)

The complete patch is available here but it is similar for all API functions. It is just the addition of the following check.

    if (dev->conn->flags & VIR_CONNECT_RO) {
        virLibConnError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
        goto error;
    }

Which checks if the device’s connection is marked as read-only and if this is the case, it will return with an “Operation Denied” error message.

According to Guido Günther this could result from modification of the system’s state up to remote execution using user data.

Written by xorl

April 29, 2011 at 20:11

Posted in bugs

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s