static int
CVE_2013_6456_libvirt1_1_0_lxcDomainDetachDeviceHostdevMiscLive(virDomainObjPtr vm,
                                     virDomainDeviceDefPtr dev)
{
    virLXCDomainObjPrivatePtr priv = vm->privateData;
    virDomainHostdevDefPtr def = NULL;
    int i, ret = -1;
    char *dst = NULL;

    if (!priv->initpid) {
        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                       _("Cannot attach disk until init PID is known"));
        goto cleanup;
    }

    if ((i = virDomainHostdevFind(vm->def,
                                  dev->data.hostdev,
                                  &def)) < 0) {
        virReportError(VIR_ERR_OPERATION_FAILED,
                       _("hostdev %s not found"),
                       dev->data.hostdev->source.caps.u.misc.chardev);
        goto cleanup;
    }

    if (virAsprintf(&dst, "/proc/%llu/root/%s",
                    (unsigned long long)priv->initpid,
                    def->source.caps.u.misc.chardev) < 0) {
        virReportOOMError();
        goto cleanup;
    }

    if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES)) {
        virReportError(VIR_ERR_OPERATION_INVALID, "%s",
                       _("devices cgroup isn't mounted"));
        goto cleanup;
    }

    VIR_DEBUG("Unlinking %s", dst);
    if (unlink(dst) < 0 && errno != ENOENT) {
        virDomainAuditHostdev(vm, def, "detach", false);
        virReportSystemError(errno,
                             _("Unable to remove device %s"), dst);
        goto cleanup;
    }
    virDomainAuditHostdev(vm, def, "detach", true);

    if (virCgroupDenyDevicePath(priv->cgroup, def->source.caps.u.misc.chardev, VIR_CGROUP_DEVICE_RWM) != 0)
        VIR_WARN("cannot deny device %s for domain %s",
                 def->source.caps.u.misc.chardev, vm->def->name);

    virDomainHostdevRemove(vm->def, i);
    virDomainHostdevDefFree(def);

    ret = 0;

cleanup:
    VIR_FREE(dst);
    return ret;
}
Esempio n. 2
0
static void
myCleanup(void)
{
    size_t i;
    for (i = 0; i < nhostdevs; i++) {
         virPCIDeviceFree(dev[i]);
         virDomainHostdevDefFree(hostdevs[i]);
    }

    if (mgr) {
        virObjectUnref(mgr->activePCIHostdevs);
        virObjectUnref(mgr->inactivePCIHostdevs);
        virObjectUnref(mgr->activeUSBHostdevs);
        VIR_FREE(mgr->stateDir);
        VIR_FREE(mgr);
    }
}
Esempio n. 3
0
static virDomainHostdevDefPtr
lxcCreateHostdevDef(int mode, int type, const char *data)
{
    virDomainHostdevDefPtr hostdev = virDomainHostdevDefAlloc(NULL);

    if (!hostdev)
        return NULL;

    hostdev->mode = mode;
    hostdev->source.caps.type = type;

    if (type == VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET &&
        VIR_STRDUP(hostdev->source.caps.u.net.iface, data) < 0) {
        virDomainHostdevDefFree(hostdev);
        hostdev = NULL;
    }

    return hostdev;
}
static void
myCleanup(void)
{
    size_t i;
    for (i = 0; i < nhostdevs; i++) {
         virPCIDeviceFree(dev[i]);
         virDomainHostdevDefFree(hostdevs[i]);
    }

    if (mgr) {
        if (!getenv("LIBVIRT_SKIP_CLEANUP"))
            virFileDeleteTree(mgr->stateDir);

        virObjectUnref(mgr->activePCIHostdevs);
        virObjectUnref(mgr->inactivePCIHostdevs);
        virObjectUnref(mgr->activeUSBHostdevs);
        VIR_FREE(mgr->stateDir);
        VIR_FREE(mgr);
    }
}
Esempio n. 5
0
static int
xenParseXLUSB(virConfPtr conf, virDomainDefPtr def)
{
    virConfValuePtr list = virConfGetValue(conf, "usbdev");
    virDomainHostdevDefPtr hostdev = NULL;

    if (list && list->type == VIR_CONF_LIST) {
        list = list->list;
        while (list) {
            char bus[3];
            char device[3];
            char *key;
            int busNum;
            int devNum;

            bus[0] = device[0] = '\0';

            if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
                goto skipusb;
            /* usbdev=['hostbus=1,hostaddr=3'] */
            key = list->str;
            while (key) {
                char *data;
                char *nextkey = strchr(key, ',');

                if (!(data = strchr(key, '=')))
                    goto skipusb;
                data++;

                if (STRPREFIX(key, "hostbus=")) {
                    int len = nextkey ? (nextkey - data) : sizeof(bus) - 1;
                    if (virStrncpy(bus, data, len, sizeof(bus)) == NULL) {
                        virReportError(VIR_ERR_INTERNAL_ERROR,
                                       _("bus %s too big for destination"),
                                       data);
                        goto skipusb;
                    }
                } else if (STRPREFIX(key, "hostaddr=")) {
                    int len = nextkey ? (nextkey - data) : sizeof(device) - 1;
                    if (virStrncpy(device, data, len, sizeof(device)) == NULL) {
                        virReportError(VIR_ERR_INTERNAL_ERROR,
                                       _("device %s too big for destination"),
                                       data);
                        goto skipusb;
                    }
                }

                while (nextkey && (nextkey[0] == ',' ||
                                   nextkey[0] == ' ' ||
                                   nextkey[0] == '\t'))
                    nextkey++;
                key = nextkey;
            }

            if (virStrToLong_i(bus, NULL, 16, &busNum) < 0)
                goto skipusb;
            if (virStrToLong_i(device, NULL, 16, &devNum) < 0)
                goto skipusb;
            if (!(hostdev = virDomainHostdevDefAlloc(NULL)))
               return -1;

            hostdev->managed = false;
            hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB;
            hostdev->source.subsys.u.usb.bus = busNum;
            hostdev->source.subsys.u.usb.device = devNum;

            if (VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, hostdev) < 0) {
                virDomainHostdevDefFree(hostdev);
                return -1;
            }

        skipusb:
            list = list->next;
        }
    }

    return 0;
}
Esempio n. 6
0
static int
lxcAddNetworkDefinition(lxcNetworkParseData *data)
{
    virDomainNetDefPtr net = NULL;
    virDomainHostdevDefPtr hostdev = NULL;
    bool isPhys, isVlan = false;
    size_t i;

    if ((data->type == NULL) || STREQ(data->type, "empty") ||
         STREQ(data->type, "") ||  STREQ(data->type, "none"))
        return 0;

    isPhys = STREQ(data->type, "phys");
    isVlan = STREQ(data->type, "vlan");
    if (data->type != NULL && (isPhys || isVlan)) {
        if (!data->link) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("Missing 'link' attribute for NIC"));
            goto error;
        }
        if (!(hostdev = lxcCreateHostdevDef(VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES,
                                            VIR_DOMAIN_HOSTDEV_CAPS_TYPE_NET,
                                            data->link)))
            goto error;

        /* This still requires the user to manually setup the vlan interface
         * on the host */
        if (isVlan && data->vlanid) {
            VIR_FREE(hostdev->source.caps.u.net.iface);
            if (virAsprintf(&hostdev->source.caps.u.net.iface,
                            "%s.%s", data->link, data->vlanid) < 0)
                goto error;
        }

        hostdev->source.caps.u.net.ips = data->ips;
        hostdev->source.caps.u.net.nips = data->nips;

        if (data->gateway_ipv4 &&
            lxcAddNetworkRouteDefinition(data->gateway_ipv4, AF_INET,
                                         &hostdev->source.caps.u.net.routes,
                                         &hostdev->source.caps.u.net.nroutes) < 0)
                goto error;

        if (data->gateway_ipv6 &&
            lxcAddNetworkRouteDefinition(data->gateway_ipv6, AF_INET6,
                                         &hostdev->source.caps.u.net.routes,
                                         &hostdev->source.caps.u.net.nroutes) < 0)
                goto error;

        if (VIR_EXPAND_N(data->def->hostdevs, data->def->nhostdevs, 1) < 0)
            goto error;
        data->def->hostdevs[data->def->nhostdevs - 1] = hostdev;
    } else {
        if (!(net = lxcCreateNetDef(data->type, data->link, data->mac,
                                    data->flag, data->macvlanmode,
                                    data->name)))
            goto error;

        net->ips = data->ips;
        net->nips = data->nips;

        if (data->gateway_ipv4 &&
            lxcAddNetworkRouteDefinition(data->gateway_ipv4, AF_INET,
                                         &net->routes,
                                         &net->nroutes) < 0)
                goto error;

        if (data->gateway_ipv6 &&
            lxcAddNetworkRouteDefinition(data->gateway_ipv6, AF_INET6,
                                         &net->routes,
                                         &net->nroutes) < 0)
                goto error;

        if (VIR_EXPAND_N(data->def->nets, data->def->nnets, 1) < 0)
            goto error;
        data->def->nets[data->def->nnets - 1] = net;
    }

    return 1;

 error:
    for (i = 0; i < data->nips; i++)
        VIR_FREE(data->ips[i]);
    VIR_FREE(data->ips);
    virDomainNetDefFree(net);
    virDomainHostdevDefFree(hostdev);
    return -1;
}