diff --git a/src/qemu/qemu_audit.c b/src/qemu/qemu_audit.c index 5bdf6555ef..40b68ff579 100644 --- a/src/qemu/qemu_audit.c +++ b/src/qemu/qemu_audit.c @@ -127,6 +127,47 @@ qemuAuditNet(virDomainObjPtr vm, VIR_FREE(vmname); } +/** + * qemuAuditNetDevice: + * @vm: domain opening a network-related device + * @def: details of network device that fd will be tied to + * @device: device being opened (such as /dev/vhost-net, + * /dev/net/tun, /dev/tanN). Note that merely opening a device + * does not mean that qemu owns it; a followup qemuAuditNet + * shows whether the fd was passed on. + * @success: true if the device was opened + * + * Log an audit message about an attempted network device open. + */ +void +qemuAuditNetDevice(virDomainDefPtr vmDef, virDomainNetDefPtr netDef, + const char *device, bool success) +{ + char uuidstr[VIR_UUID_STRING_BUFLEN]; + char macstr[VIR_MAC_STRING_BUFLEN]; + char *vmname; + char *devname; + char *rdev; + + virUUIDFormat(vmDef->uuid, uuidstr); + virFormatMacAddr(netDef->mac, macstr); + rdev = qemuAuditGetRdev(device); + + if (!(vmname = virAuditEncode("vm", vmDef->name)) || + !(devname = virAuditEncode("path", device))) { + VIR_WARN0("OOM while encoding audit message"); + goto cleanup; + } + + VIR_AUDIT(VIR_AUDIT_RECORD_RESOURCE, success, + "resrc=net reason=open %s uuid=%s net='%s' %s rdev=%s", + vmname, uuidstr, macstr, devname, VIR_AUDIT_STR(rdev)); + +cleanup: + VIR_FREE(vmname); + VIR_FREE(devname); + VIR_FREE(rdev); +} /** * qemuAuditHostdev: diff --git a/src/qemu/qemu_audit.h b/src/qemu/qemu_audit.h index a2fbe11b0f..14c7da5d29 100644 --- a/src/qemu/qemu_audit.h +++ b/src/qemu/qemu_audit.h @@ -46,6 +46,11 @@ void qemuAuditNet(virDomainObjPtr vm, const char *reason, bool success) ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(4); +void qemuAuditNetDevice(virDomainDefPtr vmDef, + virDomainNetDefPtr netDef, + const char *device, + bool success) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3); void qemuAuditHostdev(virDomainObjPtr vm, virDomainHostdevDefPtr def, const char *reason, diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 8cf1737d5d..0fc466c6e8 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -35,6 +35,7 @@ #include "uuid.h" #include "c-ctype.h" #include "domain_nwfilter.h" +#include "qemu_audit.h" #include #include @@ -97,20 +98,20 @@ uname_normalize (struct utsname *ut) /** * qemuPhysIfaceConnect: + * @def: the definition of the VM (needed by 802.1Qbh and audit) * @conn: pointer to virConnect object * @driver: pointer to the qemud_driver * @net: pointer to he VM's interface description with direct device type * @qemuCaps: flags for qemu - * @vmuuid: The UUID of the VM (needed by 802.1Qbh) * * Returns a filedescriptor on success or -1 in case of error. */ int -qemuPhysIfaceConnect(virConnectPtr conn, +qemuPhysIfaceConnect(virDomainDefPtr def, + virConnectPtr conn, struct qemud_driver *driver, virDomainNetDefPtr net, virBitmapPtr qemuCaps, - const unsigned char *vmuuid, enum virVMOperationType vmop) { int rc; @@ -124,9 +125,10 @@ qemuPhysIfaceConnect(virConnectPtr conn, vnet_hdr = 1; rc = openMacvtapTap(net->ifname, net->mac, net->data.direct.linkdev, - net->data.direct.mode, vnet_hdr, vmuuid, + net->data.direct.mode, vnet_hdr, def->uuid, &net->data.direct.virtPortProfile, &res_ifname, vmop); + qemuAuditNetDevice(def, net, res_ifname, rc >= 0); if (rc >= 0) { VIR_FREE(net->ifname); net->ifname = res_ifname; @@ -152,11 +154,11 @@ qemuPhysIfaceConnect(virConnectPtr conn, } } #else + (void)def; (void)conn; (void)net; (void)qemuCaps; (void)driver; - (void)vmuuid; (void)vmop; qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("No support for macvtap device")); @@ -167,7 +169,8 @@ qemuPhysIfaceConnect(virConnectPtr conn, int -qemuNetworkIfaceConnect(virConnectPtr conn, +qemuNetworkIfaceConnect(virDomainDefPtr def, + virConnectPtr conn, struct qemud_driver *driver, virDomainNetDefPtr net, virBitmapPtr qemuCaps) @@ -247,13 +250,10 @@ qemuNetworkIfaceConnect(virConnectPtr conn, memcpy(tapmac, net->mac, VIR_MAC_BUFLEN); tapmac[0] = 0xFE; /* Discourage bridge from using TAP dev MAC */ - if ((err = brAddTap(driver->brctl, - brname, - &net->ifname, - tapmac, - vnet_hdr, - true, - &tapfd))) { + err = brAddTap(driver->brctl, brname, &net->ifname, tapmac, + vnet_hdr, true, &tapfd); + qemuAuditNetDevice(def, net, "/dev/net/tun", tapfd >= 0); + if (err) { if (err == ENOTSUP) { /* In this particular case, give a better diagnostic. */ qemuReportError(VIR_ERR_INTERNAL_ERROR, @@ -304,7 +304,8 @@ cleanup: int -qemuOpenVhostNet(virDomainNetDefPtr net, +qemuOpenVhostNet(virDomainDefPtr def, + virDomainNetDefPtr net, virBitmapPtr qemuCaps, int *vhostfd) { @@ -342,6 +343,7 @@ qemuOpenVhostNet(virDomainNetDefPtr net, } *vhostfd = open("/dev/vhost-net", O_RDWR); + qemuAuditNetDevice(def, net, "/dev/vhost-net", *vhostfd >= 0); /* If the config says explicitly to use vhost and we couldn't open it, * report an error. @@ -3460,7 +3462,7 @@ qemuBuildCommandLine(virConnectPtr conn, if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK || net->type == VIR_DOMAIN_NET_TYPE_BRIDGE) { - int tapfd = qemuNetworkIfaceConnect(conn, driver, net, + int tapfd = qemuNetworkIfaceConnect(def, conn, driver, net, qemuCaps); if (tapfd < 0) goto error; @@ -3472,10 +3474,8 @@ qemuBuildCommandLine(virConnectPtr conn, tapfd) >= sizeof(tapfd_name)) goto no_memory; } else if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) { - int tapfd = qemuPhysIfaceConnect(conn, driver, net, - qemuCaps, - def->uuid, - vmop); + int tapfd = qemuPhysIfaceConnect(def, conn, driver, net, + qemuCaps, vmop); if (tapfd < 0) goto error; @@ -3494,7 +3494,7 @@ qemuBuildCommandLine(virConnectPtr conn, network device */ int vhostfd; - if (qemuOpenVhostNet(net, qemuCaps, &vhostfd) < 0) + if (qemuOpenVhostNet(def, net, qemuCaps, &vhostfd) < 0) goto error; if (vhostfd >= 0) { virCommandTransferFD(cmd, vhostfd); diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index 2ae364c9f4..528031da80 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -116,20 +116,22 @@ char * qemuBuildUSBHostdevDevStr(virDomainHostdevDefPtr dev); -int qemuNetworkIfaceConnect(virConnectPtr conn, +int qemuNetworkIfaceConnect(virDomainDefPtr def, + virConnectPtr conn, struct qemud_driver *driver, virDomainNetDefPtr net, virBitmapPtr qemuCaps) - ATTRIBUTE_NONNULL(1); + ATTRIBUTE_NONNULL(2); -int qemuPhysIfaceConnect(virConnectPtr conn, +int qemuPhysIfaceConnect(virDomainDefPtr def, + virConnectPtr conn, struct qemud_driver *driver, virDomainNetDefPtr net, virBitmapPtr qemuCaps, - const unsigned char *vmuuid, enum virVMOperationType vmop); -int qemuOpenVhostNet(virDomainNetDefPtr net, +int qemuOpenVhostNet(virDomainDefPtr def, + virDomainNetDefPtr net, virBitmapPtr qemuCaps, int *vhostfd); diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 540939a9ac..e4ba526010 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -576,9 +576,10 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, return -1; } - if ((tapfd = qemuNetworkIfaceConnect(conn, driver, net, qemuCaps)) < 0) + if ((tapfd = qemuNetworkIfaceConnect(vm->def, conn, driver, net, + qemuCaps)) < 0) return -1; - if (qemuOpenVhostNet(net, qemuCaps, &vhostfd) < 0) + if (qemuOpenVhostNet(vm->def, net, qemuCaps, &vhostfd) < 0) goto cleanup; } else if (net->type == VIR_DOMAIN_NET_TYPE_DIRECT) { if (priv->monConfig->type != VIR_DOMAIN_CHR_TYPE_UNIX) { @@ -589,12 +590,11 @@ int qemuDomainAttachNetDevice(virConnectPtr conn, return -1; } - if ((tapfd = qemuPhysIfaceConnect(conn, driver, net, + if ((tapfd = qemuPhysIfaceConnect(vm->def, conn, driver, net, qemuCaps, - vm->def->uuid, VIR_VM_OP_CREATE)) < 0) return -1; - if (qemuOpenVhostNet(net, qemuCaps, &vhostfd) < 0) + if (qemuOpenVhostNet(vm->def, net, qemuCaps, &vhostfd) < 0) goto cleanup; }