Skip to content
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
5a7e126
acrn: initial libvirt/ACRN import
Jul 29, 2025
c8e45c3
acrn: add implementation for domainGetCPUStats
peterfang Jun 15, 2020
cf29f45
acrn: fix connection failure
peterfang Jun 19, 2020
4c8bc32
acrn: add virtacrnd systemd services
peterfang Jun 19, 2020
97712aa
acrn_driver: use error codes in acrnGetPlatform
tttech-industrial-buchsbaum Jun 8, 2020
c6ea996
acrn_driver: use error codes in acrnInitPlatform
tttech-industrial-buchsbaum Jun 8, 2020
5f106a6
acrn: do not fail on non-ACRN systems
tttech-industrial-buchsbaum Jun 8, 2020
221d927
acrn: add RTVM support
peterfang Jun 20, 2020
e47d098
Create SECURITY.md
peterfang Jul 20, 2020
1683499
acrn_driver: introduce acrnIsRtvm
tttech-industrial-buchsbaum Jun 23, 2020
86c667f
acrn: cannot start predefined ACRN domain
tttech-industrial-buchsbaum Jun 8, 2020
dd039f1
acrn_driver: avoid duplicate read of ACRN platform data during init
tttech-industrial-buchsbaum Jun 23, 2020
8b24c6b
acrn: support the <mtu> tag when creating a tap device
peterfang Dec 17, 2020
6e47904
acrn: update getting platform info and offline cpu
wuxyintel Sep 7, 2021
9ae2926
acrn-driver: add call back to check guest persistent
wuxyintel Aug 17, 2021
405ae15
acrn-driver: enable related auto start commands
wuxyintel Aug 17, 2021
6e61522
acrn-driver: update calculation of cpu affinity and UUID
wuxyintel Nov 3, 2021
495d9e3
acrn-driver: don't pass UUID to acrn-dm
wuxyintel Nov 4, 2021
b162378
acrn-driver: fix a cpu offline bug
wuxyintel Nov 21, 2021
aac2759
acrn-driver: remove acrn-dm param `-A`
Feb 28, 2022
aa0a75d
acrn-driver: support vm destroy and force shutdown
wuxyintel Jan 25, 2022
ecb37ad
acrn-driver: support shutdown user VM gracefully
wuxyintel Feb 27, 2022
bc8c077
acrn-driver: support user VM reboot
wuxyintel Mar 1, 2022
96e0e88
acrn-driver: add CPU affinity support
Mar 1, 2022
bf101b6
acrn-driver: pass `--rtvm` to acrn-dm instead of `--lapic_pt`
Mar 9, 2022
6608042
acrn_domain : add cpu_affinity to check list
Apr 18, 2022
e87633c
acrn-driver: mapping processor and apicid
Apr 29, 2022
b28fad1
acrn-driver: allocate vCPU for Guest VM
Apr 29, 2022
3001288
acrn-driver: add vCPU info for `acrn:cpu_affinity`
Apr 29, 2022
8f18930
acrn-driver: ethernet parameter modify
Jun 6, 2022
d937d42
acrn_driver: offline CPUs in Service VM first
lifeix Aug 12, 2022
1ae2cad
acrn: fix the compilation issues
Jul 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# libvirt’s read-only privilege issue
From https://access.redhat.com/libvirt-privesc-vulnerabilities:

As the libvirt API has evolved over time, the line between “privileged” and “unprivileged” operations became less clear. API calls that were originally exposed read-only, gained more capabilities that made them more powerful, but introduced security risks that were not obvious at the time.

Administrative changes made to `/etc/libvirt/libvirtd.conf` may affect your level of exposure:
- If you have enabled the setting `listen_tcp`, network users that can reach the libvirt port may be able to conduct an attack.
- If access to libvirt is restricted by changing `unix_sock_ro_perms` to something more restrictive than `0777`, only those users able to `connect()` to the socket will be able to attack libvirtd. For example, the following allows only members of the `libvirt` group:
```
unix_sock_group = "libvirt"
unix_sock_ro_perms = "0770"
```

We recommend that users at least adopt coarse-grained access control and properly configure `unix_sock_group` and `unix_sock_ro_perms` in order to minimize libvirt's attack surface.
1 change: 1 addition & 0 deletions include/libvirt/virterror.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ typedef enum {
VIR_FROM_TPM = 70, /* Error from TPM (Since: 5.6.0) */
VIR_FROM_BPF = 71, /* Error from BPF code (Since: 5.10.0) */
VIR_FROM_CH = 72, /* Error from Cloud-Hypervisor driver (Since: 7.5.0) */
VIR_FROM_ACRN = 73, /* Error from acrn driver */

# ifdef VIR_ENUM_SENTINELS
VIR_ERR_DOMAIN_LAST /* (Since: 0.9.13) */
Expand Down
117 changes: 117 additions & 0 deletions src/acrn/Makefile.inc.am
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# vim: filetype=automake

ACRN_DRIVER_SOURCES = \
acrn/acrn_common.h \
acrn/acrn_driver.h \
acrn/acrn_driver.c \
acrn/acrn_domain.h \
acrn/acrn_domain.c \
acrn/acrn_device.h \
acrn/acrn_device.c \
acrn/acrn_monitor.h \
acrn/acrn_monitor.c \
acrn/acrn_manager.h \
acrn/acrn_manager.c \
$(NULL)

DRIVER_SOURCE_FILES += $(addprefix $(srcdir)/,$(ACRN_DRIVER_SOURCES))
STATEFUL_DRIVER_SOURCE_FILES += $(addprefix $(srcdir)/,$(ACRN_DRIVER_SOURCES))

EXTRA_DIST += $(ACRN_DRIVER_SOURCES)


if WITH_ACRN
noinst_LTLIBRARIES += libvirt_driver_acrn_impl.la
libvirt_driver_acrn_la_SOURCES =
libvirt_driver_acrn_la_LIBADD = \
libvirt_driver_acrn_impl.la \
libvirt.la \
$(GLIB_LIBS) \
$(NULL)
mod_LTLIBRARIES += libvirt_driver_acrn.la
libvirt_driver_acrn_la_LDFLAGS = $(AM_LDFLAGS_MOD_NOUNDEF)

libvirt_driver_acrn_impl_la_CFLAGS = \
-I$(srcdir)/access \
-I$(builddir)/access \
-I$(srcdir)/conf \
-I$(srcdir)/hypervisor \
$(AM_CFLAGS) \
$(NULL)
libvirt_driver_acrn_impl_la_LDFLAGS = $(AM_LDFLAGS)
libvirt_driver_acrn_impl_la_LIBADD = -luuid
libvirt_driver_acrn_impl_la_SOURCES = $(ACRN_DRIVER_SOURCES)

sbin_PROGRAMS += virtacrnd

nodist_conf_DATA += acrn/virtacrnd.conf
augeas_DATA += acrn/virtacrnd.aug
augeastest_DATA += acrn/test_virtacrnd.aug
CLEANFILES += acrn/virtacrnd.aug

virtacrnd_SOURCES = $(REMOTE_DAEMON_SOURCES)
nodist_virtacrnd_SOURCES = $(REMOTE_DAEMON_GENERATED)
virtacrnd_CFLAGS = \
$(REMOTE_DAEMON_CFLAGS) \
-DDAEMON_NAME="\"virtacrnd\"" \
-DMODULE_NAME="\"acrn\"" \
$(NULL)
virtacrnd_LDFLAGS = $(REMOTE_DAEMON_LD_FLAGS)
virtacrnd_LDADD = $(REMOTE_DAEMON_LD_ADD)

SYSTEMD_UNIT_FILES += \
virtacrnd.service \
virtacrnd.socket \
virtacrnd-ro.socket \
virtacrnd-admin.socket \
$(NULL)
SYSTEMD_UNIT_FILES_IN += \
acrn/virtacrnd.service.in \
$(NULL)

OPENRC_INIT_FILES += \
virtacrnd.init \
$(NULL)
OPENRC_INIT_FILES_IN += \
acrn/virtacrnd.init.in \
$(NULL)

VIRTACRND_UNIT_VARS = \
$(VIRTD_UNIT_VARS) \
-e 's|[@]name[@]|Libvirt acrn|g' \
-e 's|[@]service[@]|virtacrnd|g' \
-e 's|[@]sockprefix[@]|virtacrnd|g' \
$(NULL)

virtacrnd.init: acrn/virtacrnd.init.in $(top_builddir)/config.status
$(AM_V_GEN)$(SED) $(LIBVIRTD_INIT_VARS) $< > $@-t && mv $@-t $@

virtacrnd.service: acrn/virtacrnd.service.in $(top_builddir)/config.status
$(AM_V_GEN)$(SED) $(VIRTACRND_UNIT_VARS) $< > $@-t && mv $@-t $@

virtacrn%.socket: remote/libvirt%.socket.in $(top_builddir)/config.status
$(AM_V_GEN)$(SED) $(VIRTACRND_UNIT_VARS) $< > $@-t && mv $@-t $@

acrn/virtacrnd.conf: remote/libvirtd.conf.in
$(AM_V_GEN)$(SED) \
-e '/[@]CUT_ENABLE_IP[@]/,/[@]END[@]/d' \
-e 's/[@]DAEMON_NAME[@]/virtacrnd/' \
$< > $@

acrn/virtacrnd.aug: remote/libvirtd.aug.in
$(AM_V_GEN)$(SED) \
-e '/[@]CUT_ENABLE_IP[@]/,/[@]END[@]/d' \
-e 's/[@]DAEMON_NAME[@]/virtacrnd/' \
-e 's/[@]DAEMON_NAME_UC[@]/Virtacrnd/' \
$< > $@

acrn/test_virtacrnd.aug: remote/test_libvirtd.aug.in \
acrn/virtacrnd.conf $(AUG_GENTEST_SCRIPT)
$(AM_V_GEN)$(AUG_GENTEST) acrn/virtacrnd.conf \
$(srcdir)/remote/test_libvirtd.aug.in | \
$(SED) \
-e '/[@]CUT_ENABLE_IP[@]/,/[@]END[@]/d' \
-e 's/[@]DAEMON_NAME[@]/virtacrnd/' \
-e 's/[@]DAEMON_NAME_UC[@]/Virtacrnd/' \
> $@ || rm -f $@
endif WITH_ACRN
175 changes: 175 additions & 0 deletions src/acrn/acrn_device.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
#include <config.h>

#include "acrn_device.h"
#include "domain_addr.h"
#include "virlog.h"

#define VIR_FROM_THIS VIR_FROM_ACRN

VIR_LOG_INIT("acrn.acrn_device");

static int
acrnCollectPCIAddress(virDomainDefPtr def G_GNUC_UNUSED,
virDomainDeviceDefPtr dev G_GNUC_UNUSED,
virDomainDeviceInfoPtr info,
void *opaque)
{
virDomainPCIAddressSetPtr addrs;
virPCIDeviceAddressPtr addr;

if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)
return 0;

addrs = opaque;
addr = &info->addr.pci;

if (!virPCIDeviceAddressIsEmpty(addr) &&
virDomainPCIAddressReserveAddr(
addrs, addr,
VIR_PCI_CONNECT_TYPE_PCI_DEVICE, 0) < 0) {
virBuffer buf = VIR_BUFFER_INITIALIZER;

virPCIDeviceAddressFormat(&buf, *addr, false);
virReportError(VIR_ERR_INTERNAL_ERROR,
_("failed to reserve PCI addr: %s"),
virBufferCurrentContent(&buf));
virBufferFreeAndReset(&buf);
return -1;
}

return 0;
}

static virDomainPCIAddressSetPtr
acrnDomainPCIAddressSetCreate(virDomainDefPtr def, unsigned int nbuses)
{
virDomainPCIAddressSetPtr addrs;
virPCIDeviceAddress lpc_addr;

if (!(addrs = virDomainPCIAddressSetAlloc(
nbuses, VIR_PCI_ADDRESS_EXTENSION_NONE))) {
virReportError(VIR_ERR_NO_MEMORY, NULL);
return NULL;
}

if (virDomainPCIAddressBusSetModel(
&addrs->buses[0],
VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("failed to set PCI bus model"));
goto error;
}

memset(&lpc_addr, 0, sizeof(lpc_addr));
lpc_addr.slot = 0x1;

/* explicitly reserve 0:1:0 for LPC-ISA bridge */
if (virDomainPCIAddressReserveAddr(
addrs, &lpc_addr,
VIR_PCI_CONNECT_TYPE_PCI_DEVICE, 0) < 0) {
virBuffer buf = VIR_BUFFER_INITIALIZER;

virPCIDeviceAddressFormat(&buf, lpc_addr, false);
virReportError(VIR_ERR_INTERNAL_ERROR,
_("failed to reserve PCI addr for LPC-ISA bridge: %s"),
virBufferCurrentContent(&buf));
virBufferFreeAndReset(&buf);
goto error;
}

if (virDomainDeviceInfoIterate(def, acrnCollectPCIAddress, addrs) < 0)
goto error;

return addrs;

error:
virDomainPCIAddressSetFree(addrs);
return NULL;
}

static int
acrnAssignPCIAddress(virDomainDefPtr def G_GNUC_UNUSED,
virDomainDeviceDefPtr dev,
virDomainDeviceInfoPtr info,
void *opaque)
{
virDomainPCIAddressSetPtr addrs = opaque;

switch (dev->type) {
case VIR_DOMAIN_DEVICE_DISK:
case VIR_DOMAIN_DEVICE_NET:
case VIR_DOMAIN_DEVICE_HOSTDEV:
if (virDeviceInfoPCIAddressIsWanted(info) &&
virDomainPCIAddressReserveNextAddr(addrs, info,
VIR_PCI_CONNECT_TYPE_PCI_DEVICE,
-1) < 0)
goto fail;
break;
case VIR_DOMAIN_DEVICE_CONTROLLER: {
virDomainControllerDefPtr ctrl = dev->data.controller;

/* PCI hostbridge is always 0:0:0 */
if (ctrl->type != VIR_DOMAIN_CONTROLLER_TYPE_PCI &&
virDeviceInfoPCIAddressIsWanted(info) &&
virDomainPCIAddressReserveNextAddr(addrs, info,
VIR_PCI_CONNECT_TYPE_PCI_DEVICE,
-1) < 0)
goto fail;
break;
}
case VIR_DOMAIN_DEVICE_CHR: {
virDomainChrDefPtr chr = dev->data.chr;

if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO &&
virDeviceInfoPCIAddressIsWanted(info) &&
virDomainPCIAddressReserveNextAddr(addrs, info,
VIR_PCI_CONNECT_TYPE_PCI_DEVICE,
-1) < 0)
goto fail;
break;
}
case VIR_DOMAIN_DEVICE_INPUT:
case VIR_DOMAIN_DEVICE_WATCHDOG:
case VIR_DOMAIN_DEVICE_GRAPHICS:
case VIR_DOMAIN_DEVICE_RNG:
default:
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("device type %s"),
virDomainDeviceTypeToString(dev->type));
return -1;
}

return 0;

fail:
virReportError(VIR_ERR_INTERNAL_ERROR,
_("PCI addr assignment failed for device type %s"),
virDomainDeviceTypeToString(dev->type));
return -1;
}

static int
acrnDomainAssignPCIAddresses(virDomainDefPtr def)
{
virDomainPCIAddressSetPtr addrs;
int ret = -1;

if (!(addrs = acrnDomainPCIAddressSetCreate(def, 1)))
goto cleanup;

if (virDomainDeviceInfoIterate(def, acrnAssignPCIAddress, addrs) < 0)
goto cleanup;

ret = 0;

cleanup:
virDomainPCIAddressSetFree(addrs);
return ret;
}

int
acrnDomainAssignAddresses(virDomainDefPtr def)
{
return acrnDomainAssignPCIAddresses(def);
}
7 changes: 7 additions & 0 deletions src/acrn/acrn_device.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef __ACRN_DEVICE_H__
#define __ACRN_DEVICE_H__

#include "domain_conf.h"

int acrnDomainAssignAddresses(virDomainDefPtr def);
#endif /* __ACRN_DEVICE_H__ */
Loading