Skip to content

Commit 9240880

Browse files
author
Chenli Wei
committed
acrn: initial libvirt/ACRN import
Port the dev-acrn-v6.1.0 branch from the following commit to dev-acrn-v10.0.0: commit 666d8e6 Signed-off-by: Chenli Wei <chenli.wei@intel.com>
1 parent 1899d7d commit 9240880

20 files changed

Lines changed: 5033 additions & 0 deletions

SECURITY.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# libvirt’s read-only privilege issue
2+
From https://access.redhat.com/libvirt-privesc-vulnerabilities:
3+
4+
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.
5+
6+
Administrative changes made to `/etc/libvirt/libvirtd.conf` may affect your level of exposure:
7+
- If you have enabled the setting `listen_tcp`, network users that can reach the libvirt port may be able to conduct an attack.
8+
- 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:
9+
```
10+
unix_sock_group = "libvirt"
11+
unix_sock_ro_perms = "0770"
12+
```
13+
14+
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.

include/libvirt/virterror.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ typedef enum {
141141
VIR_FROM_TPM = 70, /* Error from TPM (Since: 5.6.0) */
142142
VIR_FROM_BPF = 71, /* Error from BPF code (Since: 5.10.0) */
143143
VIR_FROM_CH = 72, /* Error from Cloud-Hypervisor driver (Since: 7.5.0) */
144+
VIR_FROM_ACRN = 73, /* Error from acrn driver */
144145

145146
# ifdef VIR_ENUM_SENTINELS
146147
VIR_ERR_DOMAIN_LAST /* (Since: 0.9.13) */

src/acrn/Makefile.inc.am

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
# vim: filetype=automake
2+
3+
ACRN_DRIVER_SOURCES = \
4+
acrn/acrn_common.h \
5+
acrn/acrn_driver.h \
6+
acrn/acrn_driver.c \
7+
acrn/acrn_domain.h \
8+
acrn/acrn_domain.c \
9+
acrn/acrn_device.h \
10+
acrn/acrn_device.c \
11+
acrn/acrn_monitor.h \
12+
acrn/acrn_monitor.c \
13+
acrn/acrn_manager.h \
14+
acrn/acrn_manager.c \
15+
$(NULL)
16+
17+
DRIVER_SOURCE_FILES += $(addprefix $(srcdir)/,$(ACRN_DRIVER_SOURCES))
18+
STATEFUL_DRIVER_SOURCE_FILES += $(addprefix $(srcdir)/,$(ACRN_DRIVER_SOURCES))
19+
20+
EXTRA_DIST += $(ACRN_DRIVER_SOURCES)
21+
22+
23+
if WITH_ACRN
24+
noinst_LTLIBRARIES += libvirt_driver_acrn_impl.la
25+
libvirt_driver_acrn_la_SOURCES =
26+
libvirt_driver_acrn_la_LIBADD = \
27+
libvirt_driver_acrn_impl.la \
28+
libvirt.la \
29+
$(GLIB_LIBS) \
30+
$(NULL)
31+
mod_LTLIBRARIES += libvirt_driver_acrn.la
32+
libvirt_driver_acrn_la_LDFLAGS = $(AM_LDFLAGS_MOD_NOUNDEF)
33+
34+
libvirt_driver_acrn_impl_la_CFLAGS = \
35+
-I$(srcdir)/access \
36+
-I$(builddir)/access \
37+
-I$(srcdir)/conf \
38+
-I$(srcdir)/hypervisor \
39+
$(AM_CFLAGS) \
40+
$(NULL)
41+
libvirt_driver_acrn_impl_la_LDFLAGS = $(AM_LDFLAGS)
42+
libvirt_driver_acrn_impl_la_LIBADD = -luuid
43+
libvirt_driver_acrn_impl_la_SOURCES = $(ACRN_DRIVER_SOURCES)
44+
45+
sbin_PROGRAMS += virtacrnd
46+
47+
nodist_conf_DATA += acrn/virtacrnd.conf
48+
augeas_DATA += acrn/virtacrnd.aug
49+
augeastest_DATA += acrn/test_virtacrnd.aug
50+
CLEANFILES += acrn/virtacrnd.aug
51+
52+
virtacrnd_SOURCES = $(REMOTE_DAEMON_SOURCES)
53+
nodist_virtacrnd_SOURCES = $(REMOTE_DAEMON_GENERATED)
54+
virtacrnd_CFLAGS = \
55+
$(REMOTE_DAEMON_CFLAGS) \
56+
-DDAEMON_NAME="\"virtacrnd\"" \
57+
-DMODULE_NAME="\"acrn\"" \
58+
$(NULL)
59+
virtacrnd_LDFLAGS = $(REMOTE_DAEMON_LD_FLAGS)
60+
virtacrnd_LDADD = $(REMOTE_DAEMON_LD_ADD)
61+
62+
SYSTEMD_UNIT_FILES += \
63+
virtacrnd.service \
64+
virtacrnd.socket \
65+
virtacrnd-ro.socket \
66+
virtacrnd-admin.socket \
67+
$(NULL)
68+
SYSTEMD_UNIT_FILES_IN += \
69+
acrn/virtacrnd.service.in \
70+
$(NULL)
71+
72+
OPENRC_INIT_FILES += \
73+
virtacrnd.init \
74+
$(NULL)
75+
OPENRC_INIT_FILES_IN += \
76+
acrn/virtacrnd.init.in \
77+
$(NULL)
78+
79+
VIRTACRND_UNIT_VARS = \
80+
$(VIRTD_UNIT_VARS) \
81+
-e 's|[@]name[@]|Libvirt acrn|g' \
82+
-e 's|[@]service[@]|virtacrnd|g' \
83+
-e 's|[@]sockprefix[@]|virtacrnd|g' \
84+
$(NULL)
85+
86+
virtacrnd.init: acrn/virtacrnd.init.in $(top_builddir)/config.status
87+
$(AM_V_GEN)$(SED) $(LIBVIRTD_INIT_VARS) $< > $@-t && mv $@-t $@
88+
89+
virtacrnd.service: acrn/virtacrnd.service.in $(top_builddir)/config.status
90+
$(AM_V_GEN)$(SED) $(VIRTACRND_UNIT_VARS) $< > $@-t && mv $@-t $@
91+
92+
virtacrn%.socket: remote/libvirt%.socket.in $(top_builddir)/config.status
93+
$(AM_V_GEN)$(SED) $(VIRTACRND_UNIT_VARS) $< > $@-t && mv $@-t $@
94+
95+
acrn/virtacrnd.conf: remote/libvirtd.conf.in
96+
$(AM_V_GEN)$(SED) \
97+
-e '/[@]CUT_ENABLE_IP[@]/,/[@]END[@]/d' \
98+
-e 's/[@]DAEMON_NAME[@]/virtacrnd/' \
99+
$< > $@
100+
101+
acrn/virtacrnd.aug: remote/libvirtd.aug.in
102+
$(AM_V_GEN)$(SED) \
103+
-e '/[@]CUT_ENABLE_IP[@]/,/[@]END[@]/d' \
104+
-e 's/[@]DAEMON_NAME[@]/virtacrnd/' \
105+
-e 's/[@]DAEMON_NAME_UC[@]/Virtacrnd/' \
106+
$< > $@
107+
108+
acrn/test_virtacrnd.aug: remote/test_libvirtd.aug.in \
109+
acrn/virtacrnd.conf $(AUG_GENTEST_SCRIPT)
110+
$(AM_V_GEN)$(AUG_GENTEST) acrn/virtacrnd.conf \
111+
$(srcdir)/remote/test_libvirtd.aug.in | \
112+
$(SED) \
113+
-e '/[@]CUT_ENABLE_IP[@]/,/[@]END[@]/d' \
114+
-e 's/[@]DAEMON_NAME[@]/virtacrnd/' \
115+
-e 's/[@]DAEMON_NAME_UC[@]/Virtacrnd/' \
116+
> $@ || rm -f $@
117+
endif WITH_ACRN

src/acrn/acrn_device.c

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
#include <config.h>
2+
3+
#include "acrn_device.h"
4+
#include "domain_addr.h"
5+
#include "virlog.h"
6+
7+
#define VIR_FROM_THIS VIR_FROM_ACRN
8+
9+
VIR_LOG_INIT("acrn.acrn_device");
10+
11+
static int
12+
acrnCollectPCIAddress(virDomainDefPtr def G_GNUC_UNUSED,
13+
virDomainDeviceDefPtr dev G_GNUC_UNUSED,
14+
virDomainDeviceInfoPtr info,
15+
void *opaque)
16+
{
17+
virDomainPCIAddressSetPtr addrs;
18+
virPCIDeviceAddressPtr addr;
19+
20+
if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI)
21+
return 0;
22+
23+
addrs = opaque;
24+
addr = &info->addr.pci;
25+
26+
if (!virPCIDeviceAddressIsEmpty(addr) &&
27+
virDomainPCIAddressReserveAddr(
28+
addrs, addr,
29+
VIR_PCI_CONNECT_TYPE_PCI_DEVICE, 0) < 0) {
30+
virBuffer buf = VIR_BUFFER_INITIALIZER;
31+
32+
virPCIDeviceAddressFormat(&buf, *addr, false);
33+
virReportError(VIR_ERR_INTERNAL_ERROR,
34+
_("failed to reserve PCI addr: %s"),
35+
virBufferCurrentContent(&buf));
36+
virBufferFreeAndReset(&buf);
37+
return -1;
38+
}
39+
40+
return 0;
41+
}
42+
43+
static virDomainPCIAddressSetPtr
44+
acrnDomainPCIAddressSetCreate(virDomainDefPtr def, unsigned int nbuses)
45+
{
46+
virDomainPCIAddressSetPtr addrs;
47+
virPCIDeviceAddress lpc_addr;
48+
49+
if (!(addrs = virDomainPCIAddressSetAlloc(
50+
nbuses, VIR_PCI_ADDRESS_EXTENSION_NONE))) {
51+
virReportError(VIR_ERR_NO_MEMORY, NULL);
52+
return NULL;
53+
}
54+
55+
if (virDomainPCIAddressBusSetModel(
56+
&addrs->buses[0],
57+
VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) < 0) {
58+
virReportError(VIR_ERR_INTERNAL_ERROR,
59+
_("failed to set PCI bus model"));
60+
goto error;
61+
}
62+
63+
memset(&lpc_addr, 0, sizeof(lpc_addr));
64+
lpc_addr.slot = 0x1;
65+
66+
/* explicitly reserve 0:1:0 for LPC-ISA bridge */
67+
if (virDomainPCIAddressReserveAddr(
68+
addrs, &lpc_addr,
69+
VIR_PCI_CONNECT_TYPE_PCI_DEVICE, 0) < 0) {
70+
virBuffer buf = VIR_BUFFER_INITIALIZER;
71+
72+
virPCIDeviceAddressFormat(&buf, lpc_addr, false);
73+
virReportError(VIR_ERR_INTERNAL_ERROR,
74+
_("failed to reserve PCI addr for LPC-ISA bridge: %s"),
75+
virBufferCurrentContent(&buf));
76+
virBufferFreeAndReset(&buf);
77+
goto error;
78+
}
79+
80+
if (virDomainDeviceInfoIterate(def, acrnCollectPCIAddress, addrs) < 0)
81+
goto error;
82+
83+
return addrs;
84+
85+
error:
86+
virDomainPCIAddressSetFree(addrs);
87+
return NULL;
88+
}
89+
90+
static int
91+
acrnAssignPCIAddress(virDomainDefPtr def G_GNUC_UNUSED,
92+
virDomainDeviceDefPtr dev,
93+
virDomainDeviceInfoPtr info,
94+
void *opaque)
95+
{
96+
virDomainPCIAddressSetPtr addrs = opaque;
97+
98+
switch (dev->type) {
99+
case VIR_DOMAIN_DEVICE_DISK:
100+
case VIR_DOMAIN_DEVICE_NET:
101+
case VIR_DOMAIN_DEVICE_HOSTDEV:
102+
if (virDeviceInfoPCIAddressIsWanted(info) &&
103+
virDomainPCIAddressReserveNextAddr(addrs, info,
104+
VIR_PCI_CONNECT_TYPE_PCI_DEVICE,
105+
-1) < 0)
106+
goto fail;
107+
break;
108+
case VIR_DOMAIN_DEVICE_CONTROLLER: {
109+
virDomainControllerDefPtr ctrl = dev->data.controller;
110+
111+
/* PCI hostbridge is always 0:0:0 */
112+
if (ctrl->type != VIR_DOMAIN_CONTROLLER_TYPE_PCI &&
113+
virDeviceInfoPCIAddressIsWanted(info) &&
114+
virDomainPCIAddressReserveNextAddr(addrs, info,
115+
VIR_PCI_CONNECT_TYPE_PCI_DEVICE,
116+
-1) < 0)
117+
goto fail;
118+
break;
119+
}
120+
case VIR_DOMAIN_DEVICE_CHR: {
121+
virDomainChrDefPtr chr = dev->data.chr;
122+
123+
if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CONSOLE &&
124+
chr->targetType == VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_VIRTIO &&
125+
virDeviceInfoPCIAddressIsWanted(info) &&
126+
virDomainPCIAddressReserveNextAddr(addrs, info,
127+
VIR_PCI_CONNECT_TYPE_PCI_DEVICE,
128+
-1) < 0)
129+
goto fail;
130+
break;
131+
}
132+
case VIR_DOMAIN_DEVICE_INPUT:
133+
case VIR_DOMAIN_DEVICE_WATCHDOG:
134+
case VIR_DOMAIN_DEVICE_GRAPHICS:
135+
case VIR_DOMAIN_DEVICE_RNG:
136+
default:
137+
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
138+
_("device type %s"),
139+
virDomainDeviceTypeToString(dev->type));
140+
return -1;
141+
}
142+
143+
return 0;
144+
145+
fail:
146+
virReportError(VIR_ERR_INTERNAL_ERROR,
147+
_("PCI addr assignment failed for device type %s"),
148+
virDomainDeviceTypeToString(dev->type));
149+
return -1;
150+
}
151+
152+
static int
153+
acrnDomainAssignPCIAddresses(virDomainDefPtr def)
154+
{
155+
virDomainPCIAddressSetPtr addrs;
156+
int ret = -1;
157+
158+
if (!(addrs = acrnDomainPCIAddressSetCreate(def, 1)))
159+
goto cleanup;
160+
161+
if (virDomainDeviceInfoIterate(def, acrnAssignPCIAddress, addrs) < 0)
162+
goto cleanup;
163+
164+
ret = 0;
165+
166+
cleanup:
167+
virDomainPCIAddressSetFree(addrs);
168+
return ret;
169+
}
170+
171+
int
172+
acrnDomainAssignAddresses(virDomainDefPtr def)
173+
{
174+
return acrnDomainAssignPCIAddresses(def);
175+
}

src/acrn/acrn_device.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#ifndef __ACRN_DEVICE_H__
2+
#define __ACRN_DEVICE_H__
3+
4+
#include "domain_conf.h"
5+
6+
int acrnDomainAssignAddresses(virDomainDefPtr def);
7+
#endif /* __ACRN_DEVICE_H__ */

0 commit comments

Comments
 (0)