* [PATCH 01/15] qom: replace 'abstract' with 'flags'
2025-09-09 16:57 [PATCH <RFC> 00/15] Encode object type security status in code Daniel P. Berrangé
@ 2025-09-09 16:57 ` Daniel P. Berrangé
2025-09-09 16:57 ` [PATCH 02/15] qom: add tracking of security state of object types Daniel P. Berrangé
` (15 subsequent siblings)
16 siblings, 0 replies; 23+ messages in thread
From: Daniel P. Berrangé @ 2025-09-09 16:57 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, Paolo Bonzini, Peter Maydell, Stefan Hajnoczi,
Markus Armbruster, Thomas Huth, Daniel P. Berrangé
This will allow extra boolean flags without expending the memory
usage of the Type struct.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
qom/object.c | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/qom/object.c b/qom/object.c
index 1856bb36c7..a654765e0a 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -45,6 +45,10 @@ struct InterfaceImpl
const char *typename;
};
+enum TypeImplFlags {
+ TYPE_IMPL_FLAG_ABSTRACT = (1 << 0),
+};
+
struct TypeImpl
{
const char *name;
@@ -63,7 +67,7 @@ struct TypeImpl
void (*instance_post_init)(Object *obj);
void (*instance_finalize)(Object *obj);
- bool abstract;
+ int flags;
const char *parent;
TypeImpl *parent_type;
@@ -127,7 +131,9 @@ static TypeImpl *type_new(const TypeInfo *info)
ti->instance_post_init = info->instance_post_init;
ti->instance_finalize = info->instance_finalize;
- ti->abstract = info->abstract;
+ if (info->abstract) {
+ ti->flags |= TYPE_IMPL_FLAG_ABSTRACT;
+ }
for (i = 0; info->interfaces && info->interfaces[i].type; i++) {
ti->interfaces[i].typename = g_strdup(info->interfaces[i].type);
@@ -348,11 +354,11 @@ static void type_initialize(TypeImpl *ti)
* This means interface types are all abstract.
*/
if (ti->instance_size == 0) {
- ti->abstract = true;
+ ti->flags |= TYPE_IMPL_FLAG_ABSTRACT;
}
if (type_is_ancestor(ti, type_interface)) {
assert(ti->instance_size == 0);
- assert(ti->abstract);
+ assert(ti->flags & TYPE_IMPL_FLAG_ABSTRACT);
assert(!ti->instance_init);
assert(!ti->instance_post_init);
assert(!ti->instance_finalize);
@@ -558,7 +564,7 @@ static void object_initialize_with_type(Object *obj, size_t size, TypeImpl *type
type_initialize(type);
g_assert(type->instance_size >= sizeof(Object));
- g_assert(type->abstract == false);
+ g_assert(!(type->flags & TYPE_IMPL_FLAG_ABSTRACT));
g_assert(size >= type->instance_size);
memset(obj, 0, type->instance_size);
@@ -1045,7 +1051,7 @@ ObjectClass *object_get_class(Object *obj)
bool object_class_is_abstract(ObjectClass *klass)
{
- return klass->type->abstract;
+ return klass->type->flags & TYPE_IMPL_FLAG_ABSTRACT;
}
const char *object_class_get_name(ObjectClass *klass)
@@ -1110,7 +1116,8 @@ static void object_class_foreach_tramp(gpointer key, gpointer value,
type_initialize(type);
k = type->class;
- if (!data->include_abstract && type->abstract) {
+ if (!data->include_abstract &&
+ (type->flags & TYPE_IMPL_FLAG_ABSTRACT)) {
return;
}
--
2.50.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 02/15] qom: add tracking of security state of object types
2025-09-09 16:57 [PATCH <RFC> 00/15] Encode object type security status in code Daniel P. Berrangé
2025-09-09 16:57 ` [PATCH 01/15] qom: replace 'abstract' with 'flags' Daniel P. Berrangé
@ 2025-09-09 16:57 ` Daniel P. Berrangé
2025-09-22 21:33 ` Eric Blake
2025-09-09 16:57 ` [PATCH 03/15] machine: add 'require-secure' and 'prohibit-insecure' properties Daniel P. Berrangé
` (14 subsequent siblings)
16 siblings, 1 reply; 23+ messages in thread
From: Daniel P. Berrangé @ 2025-09-09 16:57 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, Paolo Bonzini, Peter Maydell, Stefan Hajnoczi,
Markus Armbruster, Thomas Huth, Daniel P. Berrangé
This introduces two new flags "secure" and "insecure" against
the Type struct, and helpers to check this against the ObjectClass
struct.
An object type can be considered secure if it is either marked
'secure', or is not marked 'insecure'. The gives an incremental
path where the security status is undefined for most types, but
with the possibility to require explicitly secure types, or
exclude explicitly insecure types.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
include/qom/object.h | 24 ++++++++++++++++++++++++
qom/object.c | 19 +++++++++++++++++++
2 files changed, 43 insertions(+)
diff --git a/include/qom/object.h b/include/qom/object.h
index 26df6137b9..4b9c70f06f 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -453,6 +453,11 @@ struct Object
* function.
* @abstract: If this field is true, then the class is considered abstract and
* cannot be directly instantiated.
+ * @secure: If this field is true, then the class is considered to provide
+ * a security boundary. If false, the security status is not defined.
+ * @insecure: If this field is true, then the class is considered to NOT
+ * provide a security boundary. If false, the security status is not
+ * defined.
* @class_size: The size of the class object (derivative of #ObjectClass)
* for this object. If @class_size is 0, then the size of the class will be
* assumed to be the size of the parent class. This allows a type to avoid
@@ -485,6 +490,8 @@ struct TypeInfo
void (*instance_finalize)(Object *obj);
bool abstract;
+ bool secure;
+ bool insecure;
size_t class_size;
void (*class_init)(ObjectClass *klass, const void *data);
@@ -996,6 +1003,23 @@ const char *object_class_get_name(ObjectClass *klass);
*/
bool object_class_is_abstract(ObjectClass *klass);
+/**
+ * object_class_is_secure:
+ * @klass: The class to check security of
+ *
+ * Returns: %true if @klass is declared to be secure, %false if not declared
+ */
+bool object_class_is_secure(ObjectClass *klass);
+
+
+/**
+ * object_class_is_insecure:
+ * @klass: The class to check security of
+ *
+ * Returns: %true if @klass is declared to be insecure, %false if not declared
+ */
+bool object_class_is_insecure(ObjectClass *klass);
+
/**
* object_class_by_name:
* @typename: The QOM typename to obtain the class for.
diff --git a/qom/object.c b/qom/object.c
index a654765e0a..a516ea0fea 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -47,6 +47,8 @@ struct InterfaceImpl
enum TypeImplFlags {
TYPE_IMPL_FLAG_ABSTRACT = (1 << 0),
+ TYPE_IMPL_FLAG_SECURE = (1 << 1),
+ TYPE_IMPL_FLAG_INSECURE = (1 << 2),
};
struct TypeImpl
@@ -134,6 +136,13 @@ static TypeImpl *type_new(const TypeInfo *info)
if (info->abstract) {
ti->flags |= TYPE_IMPL_FLAG_ABSTRACT;
}
+ assert(!(info->secure && info->insecure));
+ if (info->secure) {
+ ti->flags |= TYPE_IMPL_FLAG_SECURE;
+ }
+ if (info->insecure) {
+ ti->flags |= TYPE_IMPL_FLAG_INSECURE;
+ }
for (i = 0; info->interfaces && info->interfaces[i].type; i++) {
ti->interfaces[i].typename = g_strdup(info->interfaces[i].type);
@@ -1054,6 +1063,16 @@ bool object_class_is_abstract(ObjectClass *klass)
return klass->type->flags & TYPE_IMPL_FLAG_ABSTRACT;
}
+bool object_class_is_secure(ObjectClass *klass)
+{
+ return klass->type->flags & TYPE_IMPL_FLAG_SECURE;
+}
+
+bool object_class_is_insecure(ObjectClass *klass)
+{
+ return klass->type->flags & TYPE_IMPL_FLAG_INSECURE;
+}
+
const char *object_class_get_name(ObjectClass *klass)
{
return klass->type->name;
--
2.50.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH 02/15] qom: add tracking of security state of object types
2025-09-09 16:57 ` [PATCH 02/15] qom: add tracking of security state of object types Daniel P. Berrangé
@ 2025-09-22 21:33 ` Eric Blake
0 siblings, 0 replies; 23+ messages in thread
From: Eric Blake @ 2025-09-22 21:33 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Michael S. Tsirkin, Paolo Bonzini, Peter Maydell,
Stefan Hajnoczi, Markus Armbruster, Thomas Huth
On Tue, Sep 09, 2025 at 05:57:13PM +0100, Daniel P. Berrangé wrote:
> This introduces two new flags "secure" and "insecure" against
> the Type struct, and helpers to check this against the ObjectClass
> struct.
>
> An object type can be considered secure if it is either marked
> 'secure', or is not marked 'insecure'. The gives an incremental
> path where the security status is undefined for most types, but
> with the possibility to require explicitly secure types, or
> exclude explicitly insecure types.
Should there be a check in code that nothing tries to set both flags
simultaneously?
--
Eric Blake, Principal Software Engineer
Red Hat, Inc.
Virtualization: qemu.org | libguestfs.org
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 03/15] machine: add 'require-secure' and 'prohibit-insecure' properties
2025-09-09 16:57 [PATCH <RFC> 00/15] Encode object type security status in code Daniel P. Berrangé
2025-09-09 16:57 ` [PATCH 01/15] qom: replace 'abstract' with 'flags' Daniel P. Berrangé
2025-09-09 16:57 ` [PATCH 02/15] qom: add tracking of security state of object types Daniel P. Berrangé
@ 2025-09-09 16:57 ` Daniel P. Berrangé
2025-09-09 16:57 ` [PATCH 04/15] machine: check security for machine and accelerator types Daniel P. Berrangé
` (13 subsequent siblings)
16 siblings, 0 replies; 23+ messages in thread
From: Daniel P. Berrangé @ 2025-09-09 16:57 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, Paolo Bonzini, Peter Maydell, Stefan Hajnoczi,
Markus Armbruster, Thomas Huth, Daniel P. Berrangé
Both default to 'false' to maintain the historical behaviour.
If 'require-secure' is set to 'yes', then types which
explicitly declare themselves as secure are required.
If 'prohibit-insecure' is set to 'yes', then types which
explicitly declare themselves as insecure are forbidden.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/core/machine.c | 60 +++++++++++++++++++++++++++++++++++++++++++++
include/hw/boards.h | 5 ++++
2 files changed, 65 insertions(+)
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 38c949c4f2..b43c315bab 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -440,6 +440,34 @@ static void machine_set_dump_guest_core(Object *obj, bool value, Error **errp)
ms->dump_guest_core = value;
}
+static bool machine_get_require_secure(Object *obj, Error **errp)
+{
+ MachineState *ms = MACHINE(obj);
+
+ return ms->require_secure;
+}
+
+static void machine_set_require_secure(Object *obj, bool value, Error **errp)
+{
+ MachineState *ms = MACHINE(obj);
+
+ ms->require_secure = value;
+}
+
+static bool machine_get_prohibit_insecure(Object *obj, Error **errp)
+{
+ MachineState *ms = MACHINE(obj);
+
+ return ms->prohibit_insecure;
+}
+
+static void machine_set_prohibit_insecure(Object *obj, bool value, Error **errp)
+{
+ MachineState *ms = MACHINE(obj);
+
+ ms->prohibit_insecure = value;
+}
+
static bool machine_get_mem_merge(Object *obj, Error **errp)
{
MachineState *ms = MACHINE(obj);
@@ -1245,6 +1273,17 @@ static void machine_class_init(ObjectClass *oc, const void *data)
NULL, NULL);
object_class_property_set_description(oc, "memory",
"Memory size configuration");
+
+ object_class_property_add_bool(oc, "require-secure",
+ machine_get_require_secure, machine_set_require_secure);
+ object_class_property_set_description(oc, "require-secure",
+ "Define whether explicitly secure impls are required");
+
+ object_class_property_add_bool(oc, "prohibit-insecure",
+ machine_get_prohibit_insecure, machine_set_prohibit_insecure);
+ object_class_property_set_description(oc, "prohibit-insecure",
+ "Define whether explicitly insecure impls are prohibited");
+
}
static void machine_class_base_init(ObjectClass *oc, const void *data)
@@ -1269,6 +1308,8 @@ static void machine_initfn(Object *obj)
MachineClass *mc = MACHINE_GET_CLASS(obj);
ms->dump_guest_core = true;
+ ms->require_secure = false;
+ ms->prohibit_insecure = false;
ms->mem_merge = (QEMU_MADV_MERGEABLE != QEMU_MADV_INVALID);
ms->enable_graphics = true;
ms->kernel_cmdline = g_strdup("");
@@ -1362,6 +1403,25 @@ bool machine_dump_guest_core(MachineState *machine)
return machine->dump_guest_core;
}
+bool machine_check_security(MachineState *machine,
+ ObjectClass *cls,
+ Error **errp)
+{
+ if (machine->require_secure &&
+ !object_class_is_secure(cls)) {
+ error_setg(errp, "Type '%s' is not declared as secure",
+ object_class_get_name(cls));
+ return false;
+ }
+ if (machine->prohibit_insecure &&
+ object_class_is_insecure(cls)) {
+ error_setg(errp, "Type '%s' is declared as insecure",
+ object_class_get_name(cls));
+ return false;
+ }
+ return true;
+}
+
bool machine_mem_merge(MachineState *machine)
{
return machine->mem_merge;
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 665b620121..61f6942016 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -36,6 +36,9 @@ void machine_run_board_init(MachineState *machine, const char *mem_path, Error *
bool machine_usb(MachineState *machine);
int machine_phandle_start(MachineState *machine);
bool machine_dump_guest_core(MachineState *machine);
+bool machine_check_security(MachineState *machine,
+ ObjectClass *cls,
+ Error **errp);
bool machine_mem_merge(MachineState *machine);
bool machine_require_guest_memfd(MachineState *machine);
HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine);
@@ -403,6 +406,8 @@ struct MachineState {
int phandle_start;
char *dt_compatible;
bool dump_guest_core;
+ bool require_secure;
+ bool prohibit_insecure;
bool mem_merge;
bool usb;
bool usb_disabled;
--
2.50.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 04/15] machine: check security for machine and accelerator types
2025-09-09 16:57 [PATCH <RFC> 00/15] Encode object type security status in code Daniel P. Berrangé
` (2 preceding siblings ...)
2025-09-09 16:57 ` [PATCH 03/15] machine: add 'require-secure' and 'prohibit-insecure' properties Daniel P. Berrangé
@ 2025-09-09 16:57 ` Daniel P. Berrangé
2025-09-09 16:57 ` [PATCH 05/15] system: report machine security status in help output Daniel P. Berrangé
` (12 subsequent siblings)
16 siblings, 0 replies; 23+ messages in thread
From: Daniel P. Berrangé @ 2025-09-09 16:57 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, Paolo Bonzini, Peter Maydell, Stefan Hajnoczi,
Markus Armbruster, Thomas Huth, Daniel P. Berrangé
This wires up the AccelClass and MachineClass types to have their
security check when machines are initialized.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/core/machine.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/hw/core/machine.c b/hw/core/machine.c
index b43c315bab..d356710d94 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -1672,6 +1672,12 @@ void machine_run_board_init(MachineState *machine, const char *mem_path, Error *
{
ERRP_GUARD();
MachineClass *machine_class = MACHINE_GET_CLASS(machine);
+ AccelClass *ac = ACCEL_GET_CLASS(machine->accelerator);
+
+ if (!machine_check_security(machine, OBJECT_CLASS(machine_class), errp) ||
+ !machine_check_security(machine, OBJECT_CLASS(ac), errp)) {
+ return;
+ }
/* This checkpoint is required by replay to separate prior clock
reading from the other reads, because timer polling functions query
--
2.50.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 05/15] system: report machine security status in help output
2025-09-09 16:57 [PATCH <RFC> 00/15] Encode object type security status in code Daniel P. Berrangé
` (3 preceding siblings ...)
2025-09-09 16:57 ` [PATCH 04/15] machine: check security for machine and accelerator types Daniel P. Berrangé
@ 2025-09-09 16:57 ` Daniel P. Berrangé
2025-09-09 16:57 ` [PATCH 06/15] system: check security of device types Daniel P. Berrangé
` (11 subsequent siblings)
16 siblings, 0 replies; 23+ messages in thread
From: Daniel P. Berrangé @ 2025-09-09 16:57 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, Paolo Bonzini, Peter Maydell, Stefan Hajnoczi,
Markus Armbruster, Thomas Huth, Daniel P. Berrangé
When '-machine help' is given, report the security status of each
machine.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
system/vl.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/system/vl.c b/system/vl.c
index 3b7057e6c6..0695af433f 100644
--- a/system/vl.c
+++ b/system/vl.c
@@ -1578,9 +1578,11 @@ static void machine_help_func(const QDict *qdict)
if (mc->alias) {
printf("%-20s %s (alias of %s)\n", mc->alias, mc->desc, mc->name);
}
- printf("%-20s %s%s%s\n", mc->name, mc->desc,
+ printf("%-20s %s%s%s%s%s\n", mc->name, mc->desc,
mc->is_default ? " (default)" : "",
- mc->deprecation_reason ? " (deprecated)" : "");
+ mc->deprecation_reason ? " (deprecated)" : "",
+ object_class_is_secure(OBJECT_CLASS(mc)) ? " (secure)" : "",
+ object_class_is_insecure(OBJECT_CLASS(mc)) ? " (insecure)" : "");
}
}
--
2.50.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 06/15] system: check security of device types
2025-09-09 16:57 [PATCH <RFC> 00/15] Encode object type security status in code Daniel P. Berrangé
` (4 preceding siblings ...)
2025-09-09 16:57 ` [PATCH 05/15] system: report machine security status in help output Daniel P. Berrangé
@ 2025-09-09 16:57 ` Daniel P. Berrangé
2025-09-09 16:57 ` [PATCH 07/15] system: report device security status in help output Daniel P. Berrangé
` (10 subsequent siblings)
16 siblings, 0 replies; 23+ messages in thread
From: Daniel P. Berrangé @ 2025-09-09 16:57 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, Paolo Bonzini, Peter Maydell, Stefan Hajnoczi,
Markus Armbruster, Thomas Huth, Daniel P. Berrangé
This wires up the DeviceClass types to have their
security checked when devices are created.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
system/qdev-monitor.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
index 2ac92d0a07..f99907a311 100644
--- a/system/qdev-monitor.c
+++ b/system/qdev-monitor.c
@@ -644,6 +644,10 @@ DeviceState *qdev_device_add_from_qdict(const QDict *opts,
return NULL;
}
+ if (!machine_check_security(current_machine, OBJECT_CLASS(dc), errp)) {
+ return NULL;
+ }
+
/* find bus */
path = qdict_get_try_str(opts, "bus");
if (path != NULL) {
--
2.50.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 07/15] system: report device security status in help output
2025-09-09 16:57 [PATCH <RFC> 00/15] Encode object type security status in code Daniel P. Berrangé
` (5 preceding siblings ...)
2025-09-09 16:57 ` [PATCH 06/15] system: check security of device types Daniel P. Berrangé
@ 2025-09-09 16:57 ` Daniel P. Berrangé
2025-09-09 16:57 ` [PATCH 08/15] hw/core: report secure/insecure status in query-machines Daniel P. Berrangé
` (9 subsequent siblings)
16 siblings, 0 replies; 23+ messages in thread
From: Daniel P. Berrangé @ 2025-09-09 16:57 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, Paolo Bonzini, Peter Maydell, Stefan Hajnoczi,
Markus Armbruster, Thomas Huth, Daniel P. Berrangé
When '-device help' is given, report the security status of each
device.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
system/qdev-monitor.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
index f99907a311..db34b83923 100644
--- a/system/qdev-monitor.c
+++ b/system/qdev-monitor.c
@@ -164,6 +164,12 @@ static void qdev_print_devinfo(DeviceClass *dc)
if (!dc->user_creatable) {
qemu_printf(", no-user");
}
+ if (object_class_is_secure(OBJECT_CLASS(dc))) {
+ qemu_printf(", secure");
+ }
+ if (object_class_is_insecure(OBJECT_CLASS(dc))) {
+ qemu_printf(", insecure");
+ }
qemu_printf("\n");
}
--
2.50.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 08/15] hw/core: report secure/insecure status in query-machines
2025-09-09 16:57 [PATCH <RFC> 00/15] Encode object type security status in code Daniel P. Berrangé
` (6 preceding siblings ...)
2025-09-09 16:57 ` [PATCH 07/15] system: report device security status in help output Daniel P. Berrangé
@ 2025-09-09 16:57 ` Daniel P. Berrangé
2025-09-09 16:57 ` [PATCH 09/15] accel: mark 'kvm' as secure and 'tcg' as insecure Daniel P. Berrangé
` (8 subsequent siblings)
16 siblings, 0 replies; 23+ messages in thread
From: Daniel P. Berrangé @ 2025-09-09 16:57 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, Paolo Bonzini, Peter Maydell, Stefan Hajnoczi,
Markus Armbruster, Thomas Huth, Daniel P. Berrangé
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/core/machine-qmp-cmds.c | 2 ++
qapi/machine.json | 9 ++++++++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c
index 6aca1a626e..4ef2d06d32 100644
--- a/hw/core/machine-qmp-cmds.c
+++ b/hw/core/machine-qmp-cmds.c
@@ -100,6 +100,8 @@ MachineInfoList *qmp_query_machines(bool has_compat_props, bool compat_props,
if (mc->default_ram_id) {
info->default_ram_id = g_strdup(mc->default_ram_id);
}
+ info->secure = object_class_is_secure(OBJECT_CLASS(mc));
+ info->insecure = object_class_is_insecure(OBJECT_CLASS(mc));
if (compat_props && mc->compat_props) {
int i;
diff --git a/qapi/machine.json b/qapi/machine.json
index 038eab281c..ff1f9bf076 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -194,6 +194,12 @@
# present when `query-machines` argument @compat-props is true.
# (since 9.1)
#
+# @secure: If true, the machine is declared to provide a security
+# boundary from the guest; if false the status is undefined.
+#
+# @insecure: If true, the machine is declared to NOT provide a security
+# boundary from the guest; if false the status is undefined.
+#
# Features:
#
# @unstable: Member @compat-props is experimental.
@@ -207,7 +213,8 @@
'deprecated': 'bool', '*default-cpu-type': 'str',
'*default-ram-id': 'str', 'acpi': 'bool',
'*compat-props': { 'type': ['CompatProperty'],
- 'features': ['unstable'] } } }
+ 'features': ['unstable'] },
+ 'secure': 'bool', 'insecure': 'bool' } }
##
# @query-machines:
--
2.50.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 09/15] accel: mark 'kvm' as secure and 'tcg' as insecure
2025-09-09 16:57 [PATCH <RFC> 00/15] Encode object type security status in code Daniel P. Berrangé
` (7 preceding siblings ...)
2025-09-09 16:57 ` [PATCH 08/15] hw/core: report secure/insecure status in query-machines Daniel P. Berrangé
@ 2025-09-09 16:57 ` Daniel P. Berrangé
2025-09-09 16:57 ` [PATCH 10/15] hw/virtio: mark all virtio PCI devices as secure Daniel P. Berrangé
` (7 subsequent siblings)
16 siblings, 0 replies; 23+ messages in thread
From: Daniel P. Berrangé @ 2025-09-09 16:57 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, Paolo Bonzini, Peter Maydell, Stefan Hajnoczi,
Markus Armbruster, Thomas Huth, Daniel P. Berrangé
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
accel/kvm/kvm-all.c | 1 +
accel/tcg/tcg-all.c | 1 +
2 files changed, 2 insertions(+)
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index f36dfe3349..53b89d0560 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -4068,6 +4068,7 @@ static const TypeInfo kvm_accel_type = {
.instance_init = kvm_accel_instance_init,
.class_init = kvm_accel_class_init,
.instance_size = sizeof(KVMState),
+ .secure = true,
};
static void kvm_type_init(void)
diff --git a/accel/tcg/tcg-all.c b/accel/tcg/tcg-all.c
index 5125e1a4e2..3904df4e78 100644
--- a/accel/tcg/tcg-all.c
+++ b/accel/tcg/tcg-all.c
@@ -275,6 +275,7 @@ static const TypeInfo tcg_accel_type = {
.instance_init = tcg_accel_instance_init,
.class_init = tcg_accel_class_init,
.instance_size = sizeof(TCGState),
+ .insecure = true,
};
module_obj(TYPE_TCG_ACCEL);
--
2.50.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 10/15] hw/virtio: mark all virtio PCI devices as secure
2025-09-09 16:57 [PATCH <RFC> 00/15] Encode object type security status in code Daniel P. Berrangé
` (8 preceding siblings ...)
2025-09-09 16:57 ` [PATCH 09/15] accel: mark 'kvm' as secure and 'tcg' as insecure Daniel P. Berrangé
@ 2025-09-09 16:57 ` Daniel P. Berrangé
2025-09-09 16:57 ` [PATCH 11/15] hw: mark x86, s390, ppc, arm versioned machine types " Daniel P. Berrangé
` (6 subsequent siblings)
16 siblings, 0 replies; 23+ messages in thread
From: Daniel P. Berrangé @ 2025-09-09 16:57 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, Paolo Bonzini, Peter Maydell, Stefan Hajnoczi,
Markus Armbruster, Thomas Huth, Daniel P. Berrangé
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/virtio/virtio-pci.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 767216d795..f2f720792a 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -2494,6 +2494,7 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t)
.name = t->generic_name,
.parent = base_type_info.name,
.class_init = virtio_pci_generic_class_init,
+ .secure = true,
.interfaces = (const InterfaceInfo[]) {
{ INTERFACE_PCIE_DEVICE },
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
@@ -2529,6 +2530,7 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t)
.name = t->non_transitional_name,
.parent = base_type_info.name,
.instance_init = virtio_pci_non_transitional_instance_init,
+ .secure = true,
.interfaces = (const InterfaceInfo[]) {
{ INTERFACE_PCIE_DEVICE },
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
@@ -2543,6 +2545,7 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t)
.name = t->transitional_name,
.parent = base_type_info.name,
.instance_init = virtio_pci_transitional_instance_init,
+ .secure = true,
.interfaces = (const InterfaceInfo[]) {
/*
* Transitional virtio devices work only as Conventional PCI
--
2.50.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 11/15] hw: mark x86, s390, ppc, arm versioned machine types as secure
2025-09-09 16:57 [PATCH <RFC> 00/15] Encode object type security status in code Daniel P. Berrangé
` (9 preceding siblings ...)
2025-09-09 16:57 ` [PATCH 10/15] hw/virtio: mark all virtio PCI devices as secure Daniel P. Berrangé
@ 2025-09-09 16:57 ` Daniel P. Berrangé
2025-09-09 16:57 ` [PATCH 12/15] hw: declare Xen & microvm machines as secure, isapc as insecure Daniel P. Berrangé
` (5 subsequent siblings)
16 siblings, 0 replies; 23+ messages in thread
From: Daniel P. Berrangé @ 2025-09-09 16:57 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, Paolo Bonzini, Peter Maydell, Stefan Hajnoczi,
Markus Armbruster, Thomas Huth, Daniel P. Berrangé
The versioned machine types are typically present for use in
virtualization use cases and can be expected to provide a security
barrier. The only exceptions are the m68k versioned machine types
which are only used with TCG.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/arm/virt.c | 1 +
hw/ppc/spapr.c | 1 +
hw/s390x/s390-virtio-ccw.c | 1 +
include/hw/i386/pc.h | 1 +
4 files changed, 4 insertions(+)
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index e5c4142e82..f54c3c22fd 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -128,6 +128,7 @@ static void arm_virt_compat_set(MachineClass *mc)
.name = MACHINE_VER_TYPE_NAME("virt", __VA_ARGS__), \
.parent = TYPE_VIRT_MACHINE, \
.class_init = MACHINE_VER_SYM(class_init, virt, __VA_ARGS__), \
+ .secure = true, \
}; \
static void MACHINE_VER_SYM(register, virt, __VA_ARGS__)(void) \
{ \
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index eb22333404..3581f581a4 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -4748,6 +4748,7 @@ static void spapr_machine_latest_class_options(MachineClass *mc)
.name = MACHINE_VER_TYPE_NAME("pseries", __VA_ARGS__), \
.parent = TYPE_SPAPR_MACHINE, \
.class_init = MACHINE_VER_SYM(class_init, spapr, __VA_ARGS__), \
+ .secure = true, \
}; \
static void MACHINE_VER_SYM(register, spapr, __VA_ARGS__)(void) \
{ \
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index d0c6e80cb0..54bc4e1b74 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -896,6 +896,7 @@ static const TypeInfo ccw_machine_info = {
.name = MACHINE_VER_TYPE_NAME("s390-ccw-virtio", __VA_ARGS__), \
.parent = TYPE_S390_CCW_MACHINE, \
.class_init = MACHINE_VER_SYM(class_init, ccw, __VA_ARGS__), \
+ .secure = true, \
}; \
static void MACHINE_VER_SYM(register, ccw, __VA_ARGS__)(void) \
{ \
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index e83157ab35..7c31bf1444 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -342,6 +342,7 @@ extern const size_t pc_compat_2_6_len;
.name = MACHINE_VER_TYPE_NAME(namestr, __VA_ARGS__), \
.parent = TYPE_PC_MACHINE, \
.class_init = MACHINE_VER_SYM(class_init, namesym, __VA_ARGS__), \
+ .secure = true, \
}; \
static void MACHINE_VER_SYM(register, namesym, __VA_ARGS__)(void) \
{ \
--
2.50.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 12/15] hw: declare Xen & microvm machines as secure, isapc as insecure
2025-09-09 16:57 [PATCH <RFC> 00/15] Encode object type security status in code Daniel P. Berrangé
` (10 preceding siblings ...)
2025-09-09 16:57 ` [PATCH 11/15] hw: mark x86, s390, ppc, arm versioned machine types " Daniel P. Berrangé
@ 2025-09-09 16:57 ` Daniel P. Berrangé
2025-09-09 16:57 ` [PATCH 13/15] hw/core: declare 'none' machine to be insecure Daniel P. Berrangé
` (4 subsequent siblings)
16 siblings, 0 replies; 23+ messages in thread
From: Daniel P. Berrangé @ 2025-09-09 16:57 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, Paolo Bonzini, Peter Maydell, Stefan Hajnoczi,
Markus Armbruster, Thomas Huth, Daniel P. Berrangé
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/arm/xen-pvh.c | 1 +
hw/i386/isapc.c | 2 +-
hw/i386/microvm.c | 1 +
hw/i386/pc_piix.c | 4 ++--
hw/i386/xen/xen-pvh.c | 1 +
hw/i386/xen/xen_pvdevice.c | 1 +
hw/xen/xen-pvh-common.c | 1 +
hw/xenpv/xen_machine_pv.c | 2 +-
include/hw/boards.h | 13 ++++++++++++-
include/hw/i386/pc.h | 4 +++-
10 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/hw/arm/xen-pvh.c b/hw/arm/xen-pvh.c
index 1a9eeb01c8..d6b777cb20 100644
--- a/hw/arm/xen-pvh.c
+++ b/hw/arm/xen-pvh.c
@@ -95,6 +95,7 @@ static const TypeInfo xen_arm_machine_type = {
.class_init = xen_arm_machine_class_init,
.instance_size = sizeof(XenPVHMachineState),
.instance_init = xen_arm_instance_init,
+ .secure = true,
};
static void xen_arm_machine_register_types(void)
diff --git a/hw/i386/isapc.c b/hw/i386/isapc.c
index 44f4a44672..4564baa5dc 100644
--- a/hw/i386/isapc.c
+++ b/hw/i386/isapc.c
@@ -186,4 +186,4 @@ static void isapc_machine_options(MachineClass *m)
}
DEFINE_PC_MACHINE(isapc, "isapc", pc_init_isa,
- isapc_machine_options);
+ isapc_machine_options, false);
diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c
index 94d22a232a..c9ff29da0e 100644
--- a/hw/i386/microvm.c
+++ b/hw/i386/microvm.c
@@ -729,6 +729,7 @@ static const TypeInfo microvm_machine_info = {
.instance_init = microvm_machine_initfn,
.class_size = sizeof(MicrovmMachineClass),
.class_init = microvm_class_init,
+ .secure = true,
.interfaces = (const InterfaceInfo[]) {
{ TYPE_HOTPLUG_HANDLER },
{ }
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index caf8bab68e..168f1821b6 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -756,7 +756,7 @@ static void xenfv_machine_4_2_options(MachineClass *m)
}
DEFINE_PC_MACHINE(xenfv_4_2, "xenfv-4.2", pc_xen_hvm_init,
- xenfv_machine_4_2_options);
+ xenfv_machine_4_2_options, true);
static void xenfv_machine_3_1_options(MachineClass *m)
{
@@ -768,5 +768,5 @@ static void xenfv_machine_3_1_options(MachineClass *m)
}
DEFINE_PC_MACHINE(xenfv, "xenfv-3.1", pc_xen_hvm_init,
- xenfv_machine_3_1_options);
+ xenfv_machine_3_1_options, true);
#endif
diff --git a/hw/i386/xen/xen-pvh.c b/hw/i386/xen/xen-pvh.c
index 067f73e977..f30cb82962 100644
--- a/hw/i386/xen/xen-pvh.c
+++ b/hw/i386/xen/xen-pvh.c
@@ -115,6 +115,7 @@ static const TypeInfo xen_pvh_x86_machine_type = {
.class_init = xen_pvh_machine_class_init,
.instance_init = xen_pvh_instance_init,
.instance_size = sizeof(XenPVHx86State),
+ .secure = true,
};
static void xen_pvh_machine_register_types(void)
diff --git a/hw/i386/xen/xen_pvdevice.c b/hw/i386/xen/xen_pvdevice.c
index 87a974ae5a..adf4948b9a 100644
--- a/hw/i386/xen/xen_pvdevice.c
+++ b/hw/i386/xen/xen_pvdevice.c
@@ -139,6 +139,7 @@ static const TypeInfo xen_pv_type_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(XenPVDevice),
.class_init = xen_pv_class_init,
+ .secure = true,
.interfaces = (const InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ },
diff --git a/hw/xen/xen-pvh-common.c b/hw/xen/xen-pvh-common.c
index b93ff80c85..5b1572f531 100644
--- a/hw/xen/xen-pvh-common.c
+++ b/hw/xen/xen-pvh-common.c
@@ -389,6 +389,7 @@ static const TypeInfo xen_pvh_info = {
.instance_size = sizeof(XenPVHMachineState),
.class_size = sizeof(XenPVHMachineClass),
.class_init = xen_pvh_class_init,
+ .secure = true,
};
static void xen_pvh_register_types(void)
diff --git a/hw/xenpv/xen_machine_pv.c b/hw/xenpv/xen_machine_pv.c
index 99c02492ef..26a77ef007 100644
--- a/hw/xenpv/xen_machine_pv.c
+++ b/hw/xenpv/xen_machine_pv.c
@@ -69,4 +69,4 @@ static void xenpv_machine_init(MachineClass *mc)
mc->default_machine_opts = "accel=xen";
}
-DEFINE_MACHINE("xenpv", xenpv_machine_init)
+DEFINE_SECURE_MACHINE("xenpv", xenpv_machine_init)
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 61f6942016..bef22d917d 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -767,7 +767,7 @@ struct MachineState {
} \
} while (0)
-#define DEFINE_MACHINE(namestr, machine_initfn) \
+#define DEFINE_MACHINE_IMPL(namestr, machine_initfn, issecure, isinsecure) \
static void machine_initfn##_class_init(ObjectClass *oc, const void *data) \
{ \
MachineClass *mc = MACHINE_CLASS(oc); \
@@ -777,6 +777,8 @@ struct MachineState {
.name = MACHINE_TYPE_NAME(namestr), \
.parent = TYPE_MACHINE, \
.class_init = machine_initfn##_class_init, \
+ .secure = issecure, \
+ .insecure = isinsecure, \
}; \
static void machine_initfn##_register_types(void) \
{ \
@@ -784,6 +786,15 @@ struct MachineState {
} \
type_init(machine_initfn##_register_types)
+#define DEFINE_MACHINE(namestr, machine_initfn) \
+ DEFINE_MACHINE_IMPL(namestr, machine_initfn, false, false)
+
+#define DEFINE_SECURE_MACHINE(namestr, machine_initfn) \
+ DEFINE_MACHINE_IMPL(namestr, machine_initfn, true, false)
+
+#define DEFINE_INSECURE_MACHINE(namestr, machine_initfn) \
+ DEFINE_MACHINE_IMPL(namestr, machine_initfn, false, true)
+
extern GlobalProperty hw_compat_10_1[];
extern const size_t hw_compat_10_1_len;
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 7c31bf1444..8b76d21825 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -301,7 +301,7 @@ extern const size_t pc_compat_2_7_len;
extern GlobalProperty pc_compat_2_6[];
extern const size_t pc_compat_2_6_len;
-#define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn) \
+#define DEFINE_PC_MACHINE(suffix, namestr, initfn, optsfn, issecure) \
static void pc_machine_##suffix##_class_init(ObjectClass *oc, \
const void *data) \
{ \
@@ -313,6 +313,8 @@ extern const size_t pc_compat_2_6_len;
.name = namestr TYPE_MACHINE_SUFFIX, \
.parent = TYPE_PC_MACHINE, \
.class_init = pc_machine_##suffix##_class_init, \
+ .secure = issecure, \
+ .insecure = !issecure, \
}; \
static void pc_machine_init_##suffix(void) \
{ \
--
2.50.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 13/15] hw/core: declare 'none' machine to be insecure
2025-09-09 16:57 [PATCH <RFC> 00/15] Encode object type security status in code Daniel P. Berrangé
` (11 preceding siblings ...)
2025-09-09 16:57 ` [PATCH 12/15] hw: declare Xen & microvm machines as secure, isapc as insecure Daniel P. Berrangé
@ 2025-09-09 16:57 ` Daniel P. Berrangé
2025-09-09 16:57 ` [PATCH 14/15] hw/net: mark all NICs as insecure except e1000, e1000e & xen Daniel P. Berrangé
` (3 subsequent siblings)
16 siblings, 0 replies; 23+ messages in thread
From: Daniel P. Berrangé @ 2025-09-09 16:57 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, Paolo Bonzini, Peter Maydell, Stefan Hajnoczi,
Markus Armbruster, Thomas Huth, Daniel P. Berrangé
This machine is only used for probing capabilities and thus will
not run any guest workloads & has no reason to be considered secure
at this time.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/core/null-machine.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c
index a6e477a2d8..c2ff8b1b5b 100644
--- a/hw/core/null-machine.c
+++ b/hw/core/null-machine.c
@@ -55,4 +55,4 @@ static void machine_none_machine_init(MachineClass *mc)
mc->no_cdrom = 1;
}
-DEFINE_MACHINE("none", machine_none_machine_init)
+DEFINE_INSECURE_MACHINE("none", machine_none_machine_init)
--
2.50.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 14/15] hw/net: mark all NICs as insecure except e1000, e1000e & xen
2025-09-09 16:57 [PATCH <RFC> 00/15] Encode object type security status in code Daniel P. Berrangé
` (12 preceding siblings ...)
2025-09-09 16:57 ` [PATCH 13/15] hw/core: declare 'none' machine to be insecure Daniel P. Berrangé
@ 2025-09-09 16:57 ` Daniel P. Berrangé
2025-09-09 16:57 ` [PATCH 15/15] docs: expand security docs with info about secure/insecure markers Daniel P. Berrangé
` (2 subsequent siblings)
16 siblings, 0 replies; 23+ messages in thread
From: Daniel P. Berrangé @ 2025-09-09 16:57 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, Paolo Bonzini, Peter Maydell, Stefan Hajnoczi,
Markus Armbruster, Thomas Huth, Daniel P. Berrangé
Historically most NICs are only interesting for non-virtualization
use cases and have not been written with malicious guests in mind.
The exception is a handful of NICs from the x86 world. These days
virtio-net or xen-net should be used in all virtualized guests.
An exception is made, however, for the e1000/e1000e NICs since
they are a common fallback NIC option for scenarios where virtio
is not available.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
hw/net/allwinner-sun8i-emac.c | 1 +
hw/net/allwinner_emac.c | 3 ++-
hw/net/cadence_gem.c | 1 +
hw/net/can/can_kvaser_pci.c | 1 +
hw/net/can/can_mioe3680_pci.c | 1 +
hw/net/can/can_pcm3680_pci.c | 1 +
hw/net/can/ctucan_pci.c | 1 +
hw/net/can/xlnx-versal-canfd.c | 1 +
hw/net/can/xlnx-zynqmp-can.c | 1 +
hw/net/dp8393x.c | 1 +
hw/net/e1000.c | 1 +
hw/net/e1000e.c | 1 +
hw/net/eepro100.c | 1 +
hw/net/fsl_etsec/etsec.c | 1 +
hw/net/ftgmac100.c | 1 +
hw/net/igb.c | 1 +
hw/net/igbvf.c | 1 +
hw/net/imx_fec.c | 2 ++
hw/net/lan9118.c | 1 +
hw/net/lan9118_phy.c | 1 +
hw/net/lance.c | 1 +
hw/net/lasi_i82596.c | 1 +
hw/net/mcf_fec.c | 1 +
hw/net/msf2-emac.c | 1 +
hw/net/mv88w8618_eth.c | 1 +
hw/net/ne2000-isa.c | 1 +
hw/net/ne2000-pci.c | 1 +
hw/net/npcm7xx_emc.c | 1 +
hw/net/npcm_gmac.c | 1 +
hw/net/npcm_pcs.c | 1 +
hw/net/opencores_eth.c | 1 +
hw/net/pcnet-pci.c | 1 +
hw/net/rocker/rocker.c | 1 +
hw/net/rtl8139.c | 1 +
hw/net/smc91c111.c | 1 +
hw/net/spapr_llan.c | 1 +
hw/net/stellaris_enet.c | 1 +
hw/net/sungem.c | 1 +
hw/net/sunhme.c | 1 +
hw/net/tulip.c | 1 +
hw/net/virtio-net.c | 1 +
hw/net/vmxnet3.c | 1 +
hw/net/xen_nic.c | 1 +
hw/net/xgmac.c | 1 +
hw/net/xilinx_axienet.c | 1 +
hw/net/xilinx_ethlite.c | 1 +
46 files changed, 48 insertions(+), 1 deletion(-)
diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c
index 30a81576b4..9239be7a2b 100644
--- a/hw/net/allwinner-sun8i-emac.c
+++ b/hw/net/allwinner-sun8i-emac.c
@@ -892,6 +892,7 @@ static const TypeInfo allwinner_sun8i_emac_info = {
.instance_size = sizeof(AwSun8iEmacState),
.instance_init = allwinner_sun8i_emac_init,
.class_init = allwinner_sun8i_emac_class_init,
+ .insecure = true,
};
static void allwinner_sun8i_emac_register_types(void)
diff --git a/hw/net/allwinner_emac.c b/hw/net/allwinner_emac.c
index 77d089d988..2c2cd68aae 100644
--- a/hw/net/allwinner_emac.c
+++ b/hw/net/allwinner_emac.c
@@ -528,8 +528,9 @@ static const TypeInfo aw_emac_info = {
.name = TYPE_AW_EMAC,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(AwEmacState),
- .instance_init = aw_emac_init,
+ .instance_init = aw_emac_init,
.class_init = aw_emac_class_init,
+ .insecure = true,
};
static void aw_emac_register_types(void)
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index 44446666de..0d9894a95a 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -1833,6 +1833,7 @@ static const TypeInfo gem_info = {
.instance_size = sizeof(CadenceGEMState),
.instance_init = gem_init,
.class_init = gem_class_init,
+ .insecure = true,
};
static void gem_register_types(void)
diff --git a/hw/net/can/can_kvaser_pci.c b/hw/net/can/can_kvaser_pci.c
index be16769de2..d22d8af9d0 100644
--- a/hw/net/can/can_kvaser_pci.c
+++ b/hw/net/can/can_kvaser_pci.c
@@ -305,6 +305,7 @@ static const TypeInfo kvaser_pci_info = {
.instance_size = sizeof(KvaserPCIState),
.class_init = kvaser_pci_class_init,
.instance_init = kvaser_pci_instance_init,
+ .insecure = true,
.interfaces = (const InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ },
diff --git a/hw/net/can/can_mioe3680_pci.c b/hw/net/can/can_mioe3680_pci.c
index 44f3ba370d..9d73b3da8f 100644
--- a/hw/net/can/can_mioe3680_pci.c
+++ b/hw/net/can/can_mioe3680_pci.c
@@ -248,6 +248,7 @@ static const TypeInfo mioe3680_pci_info = {
.instance_size = sizeof(Mioe3680PCIState),
.class_init = mioe3680_pci_class_init,
.instance_init = mioe3680_pci_instance_init,
+ .insecure = true,
.interfaces = (const InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ },
diff --git a/hw/net/can/can_pcm3680_pci.c b/hw/net/can/can_pcm3680_pci.c
index 7296d63be7..dd17f184e9 100644
--- a/hw/net/can/can_pcm3680_pci.c
+++ b/hw/net/can/can_pcm3680_pci.c
@@ -249,6 +249,7 @@ static const TypeInfo pcm3680i_pci_info = {
.instance_size = sizeof(Pcm3680iPCIState),
.class_init = pcm3680i_pci_class_init,
.instance_init = pcm3680i_pci_instance_init,
+ .insecure = true,
.interfaces = (const InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ },
diff --git a/hw/net/can/ctucan_pci.c b/hw/net/can/ctucan_pci.c
index bed6785433..24dbd2b7c5 100644
--- a/hw/net/can/ctucan_pci.c
+++ b/hw/net/can/ctucan_pci.c
@@ -262,6 +262,7 @@ static const TypeInfo ctucan_pci_info = {
.instance_size = sizeof(CtuCanPCIState),
.class_init = ctucan_pci_class_init,
.instance_init = ctucan_pci_instance_init,
+ .insecure = true,
.interfaces = (const InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ },
diff --git a/hw/net/can/xlnx-versal-canfd.c b/hw/net/can/xlnx-versal-canfd.c
index 3eb111949f..3bd3e92c29 100644
--- a/hw/net/can/xlnx-versal-canfd.c
+++ b/hw/net/can/xlnx-versal-canfd.c
@@ -2068,6 +2068,7 @@ static const TypeInfo canfd_info = {
.instance_size = sizeof(XlnxVersalCANFDState),
.class_init = canfd_class_init,
.instance_init = canfd_init,
+ .insecure = true,
};
static void canfd_register_types(void)
diff --git a/hw/net/can/xlnx-zynqmp-can.c b/hw/net/can/xlnx-zynqmp-can.c
index ca9edd4a5b..c9a21e0fe5 100644
--- a/hw/net/can/xlnx-zynqmp-can.c
+++ b/hw/net/can/xlnx-zynqmp-can.c
@@ -1194,6 +1194,7 @@ static const TypeInfo can_info = {
.instance_size = sizeof(XlnxZynqMPCANState),
.class_init = xlnx_zynqmp_can_class_init,
.instance_init = xlnx_zynqmp_can_init,
+ .insecure = true,
};
static void can_register_types(void)
diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index d49032059b..06e0da8052 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -956,6 +956,7 @@ static const TypeInfo dp8393x_info = {
.instance_size = sizeof(dp8393xState),
.instance_init = dp8393x_instance_init,
.class_init = dp8393x_class_init,
+ .insecure = true,
};
static void dp8393x_register_types(void)
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index a80a7b0cdb..684350557f 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -1759,6 +1759,7 @@ static void e1000_register_types(void)
type_info.parent = TYPE_E1000_BASE;
type_info.class_data = info;
type_info.class_init = e1000_class_init;
+ type_info.secure = true,
type_register_static(&type_info);
}
diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c
index 89e6d52ba0..83cf3cf643 100644
--- a/hw/net/e1000e.c
+++ b/hw/net/e1000e.c
@@ -721,6 +721,7 @@ static const TypeInfo e1000e_info = {
.instance_size = sizeof(E1000EState),
.class_init = e1000e_class_init,
.instance_init = e1000e_instance_init,
+ .secure = true,
.interfaces = (const InterfaceInfo[]) {
{ INTERFACE_PCIE_DEVICE },
{ }
diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index d47df5a97f..78c7bb1a12 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -2094,6 +2094,7 @@ static void eepro100_register_types(void)
type_info.class_init = eepro100_class_init;
type_info.instance_size = sizeof(EEPRO100State);
type_info.instance_init = eepro100_instance_init;
+ type_info.insecure = true,
type_info.interfaces = (const InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ },
diff --git a/hw/net/fsl_etsec/etsec.c b/hw/net/fsl_etsec/etsec.c
index 846f6cbc5d..474b941ba5 100644
--- a/hw/net/fsl_etsec/etsec.c
+++ b/hw/net/fsl_etsec/etsec.c
@@ -437,6 +437,7 @@ static const TypeInfo etsec_types[] = {
.instance_size = sizeof(eTSEC),
.class_init = etsec_class_init,
.instance_init = etsec_instance_init,
+ .insecure = true,
},
};
diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c
index c41ce889cf..7243ad8a02 100644
--- a/hw/net/ftgmac100.c
+++ b/hw/net/ftgmac100.c
@@ -1277,6 +1277,7 @@ static const TypeInfo ftgmac100_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(FTGMAC100State),
.class_init = ftgmac100_class_init,
+ .insecure = true,
};
/*
diff --git a/hw/net/igb.c b/hw/net/igb.c
index e4c02365d6..2ce8582e76 100644
--- a/hw/net/igb.c
+++ b/hw/net/igb.c
@@ -635,6 +635,7 @@ static const TypeInfo igb_info = {
.instance_size = sizeof(IGBState),
.class_init = igb_class_init,
.instance_init = igb_instance_init,
+ .insecure = true,
.interfaces = (const InterfaceInfo[]) {
{ INTERFACE_PCIE_DEVICE },
{ }
diff --git a/hw/net/igbvf.c b/hw/net/igbvf.c
index 31d72c4977..2072b7a169 100644
--- a/hw/net/igbvf.c
+++ b/hw/net/igbvf.c
@@ -325,6 +325,7 @@ static const TypeInfo igbvf_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(IgbVfState),
.class_init = igbvf_class_init,
+ .insecure = true,
.interfaces = (const InterfaceInfo[]) {
{ INTERFACE_PCIE_DEVICE },
{ }
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index e5e34dd1a4..22f20dc048 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -1261,12 +1261,14 @@ static const TypeInfo imx_fec_info = {
.instance_size = sizeof(IMXFECState),
.instance_init = imx_fec_init,
.class_init = imx_eth_class_init,
+ .insecure = true,
};
static const TypeInfo imx_enet_info = {
.name = TYPE_IMX_ENET,
.parent = TYPE_IMX_FEC,
.instance_init = imx_enet_init,
+ .insecure = true,
};
static void imx_eth_register_types(void)
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
index 3017e12971..f59468aa34 100644
--- a/hw/net/lan9118.c
+++ b/hw/net/lan9118.c
@@ -1325,6 +1325,7 @@ static const TypeInfo lan9118_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(lan9118_state),
.class_init = lan9118_class_init,
+ .insecure = true,
};
static void lan9118_register_types(void)
diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c
index 4c4e03df11..305c019a68 100644
--- a/hw/net/lan9118_phy.c
+++ b/hw/net/lan9118_phy.c
@@ -216,6 +216,7 @@ static const TypeInfo types[] = {
.instance_size = sizeof(Lan9118PhyState),
.instance_init = lan9118_phy_init,
.class_init = lan9118_phy_class_init,
+ .insecure = true,
}
};
diff --git a/hw/net/lance.c b/hw/net/lance.c
index dfb855c23a..314d1eeae3 100644
--- a/hw/net/lance.c
+++ b/hw/net/lance.c
@@ -161,6 +161,7 @@ static const TypeInfo lance_info = {
.instance_size = sizeof(SysBusPCNetState),
.class_init = lance_class_init,
.instance_init = lance_instance_init,
+ .insecure = true,
};
static void lance_register_types(void)
diff --git a/hw/net/lasi_i82596.c b/hw/net/lasi_i82596.c
index 9e1dd21546..56ee1688d1 100644
--- a/hw/net/lasi_i82596.c
+++ b/hw/net/lasi_i82596.c
@@ -181,6 +181,7 @@ static const TypeInfo lasi_82596_info = {
.instance_size = sizeof(SysBusI82596State),
.class_init = lasi_82596_class_init,
.instance_init = lasi_82596_instance_init,
+ .insecure = true,
};
static void lasi_82596_register_types(void)
diff --git a/hw/net/mcf_fec.c b/hw/net/mcf_fec.c
index ae128fa311..20d2bc3fd3 100644
--- a/hw/net/mcf_fec.c
+++ b/hw/net/mcf_fec.c
@@ -681,6 +681,7 @@ static const TypeInfo mcf_fec_info = {
.instance_size = sizeof(mcf_fec_state),
.instance_init = mcf_fec_instance_init,
.class_init = mcf_fec_class_init,
+ .insecure = true,
};
static void mcf_fec_register_types(void)
diff --git a/hw/net/msf2-emac.c b/hw/net/msf2-emac.c
index 59045973ab..d92e0bee09 100644
--- a/hw/net/msf2-emac.c
+++ b/hw/net/msf2-emac.c
@@ -581,6 +581,7 @@ static const TypeInfo msf2_emac_info = {
.instance_size = sizeof(MSF2EmacState),
.instance_init = msf2_emac_init,
.class_init = msf2_emac_class_init,
+ .insecure = true,
};
static void msf2_emac_register_types(void)
diff --git a/hw/net/mv88w8618_eth.c b/hw/net/mv88w8618_eth.c
index 6f08846c81..56a1e9dff3 100644
--- a/hw/net/mv88w8618_eth.c
+++ b/hw/net/mv88w8618_eth.c
@@ -392,6 +392,7 @@ static const TypeInfo mv88w8618_eth_info = {
.instance_size = sizeof(mv88w8618_eth_state),
.instance_init = mv88w8618_eth_init,
.class_init = mv88w8618_eth_class_init,
+ .insecure = true,
};
static void musicpal_register_types(void)
diff --git a/hw/net/ne2000-isa.c b/hw/net/ne2000-isa.c
index 673c785abc..cb3ffc7668 100644
--- a/hw/net/ne2000-isa.c
+++ b/hw/net/ne2000-isa.c
@@ -142,6 +142,7 @@ static const TypeInfo ne2000_isa_info = {
.instance_size = sizeof(ISANE2000State),
.class_init = isa_ne2000_class_initfn,
.instance_init = isa_ne2000_instance_init,
+ .insecure = true,
};
static void ne2000_isa_register_types(void)
diff --git a/hw/net/ne2000-pci.c b/hw/net/ne2000-pci.c
index ce937e1b61..b1381efb89 100644
--- a/hw/net/ne2000-pci.c
+++ b/hw/net/ne2000-pci.c
@@ -122,6 +122,7 @@ static const TypeInfo ne2000_info = {
.instance_size = sizeof(PCINE2000State),
.class_init = ne2000_class_init,
.instance_init = ne2000_instance_init,
+ .insecure = true,
.interfaces = (const InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ },
diff --git a/hw/net/npcm7xx_emc.c b/hw/net/npcm7xx_emc.c
index 9ba35e2c81..b8f7cb9135 100644
--- a/hw/net/npcm7xx_emc.c
+++ b/hw/net/npcm7xx_emc.c
@@ -867,6 +867,7 @@ static const TypeInfo npcm7xx_emc_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(NPCM7xxEMCState),
.class_init = npcm7xx_emc_class_init,
+ .insecure = true,
};
static void npcm7xx_emc_register_type(void)
diff --git a/hw/net/npcm_gmac.c b/hw/net/npcm_gmac.c
index 5e32cd3edf..bafbee028f 100644
--- a/hw/net/npcm_gmac.c
+++ b/hw/net/npcm_gmac.c
@@ -933,6 +933,7 @@ static const TypeInfo npcm_gmac_types[] = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(NPCMGMACState),
.class_init = npcm_gmac_class_init,
+ .insecure = true,
},
};
DEFINE_TYPES(npcm_gmac_types)
diff --git a/hw/net/npcm_pcs.c b/hw/net/npcm_pcs.c
index 6aec105271..42ee30382c 100644
--- a/hw/net/npcm_pcs.c
+++ b/hw/net/npcm_pcs.c
@@ -405,6 +405,7 @@ static const TypeInfo npcm_pcs_types[] = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(NPCMPCSState),
.class_init = npcm_pcs_class_init,
+ .insecure = true,
},
};
DEFINE_TYPES(npcm_pcs_types)
diff --git a/hw/net/opencores_eth.c b/hw/net/opencores_eth.c
index 7e955c0132..3d03f8fd73 100644
--- a/hw/net/opencores_eth.c
+++ b/hw/net/opencores_eth.c
@@ -763,6 +763,7 @@ static const TypeInfo open_eth_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(OpenEthState),
.class_init = open_eth_class_init,
+ .insecure = true,
};
static void open_eth_register_types(void)
diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c
index 0ca5bc2193..2ad441e78a 100644
--- a/hw/net/pcnet-pci.c
+++ b/hw/net/pcnet-pci.c
@@ -280,6 +280,7 @@ static const TypeInfo pcnet_info = {
.instance_size = sizeof(PCIPCNetState),
.class_init = pcnet_class_init,
.instance_init = pcnet_instance_init,
+ .insecure = true,
.interfaces = (const InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ },
diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c
index cc49701dd3..5e8ecf1c02 100644
--- a/hw/net/rocker/rocker.c
+++ b/hw/net/rocker/rocker.c
@@ -1498,6 +1498,7 @@ static const TypeInfo rocker_info = {
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(Rocker),
.class_init = rocker_class_init,
+ .insecure = true,
.interfaces = (const InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ },
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 324fb932aa..a6147099f3 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -3439,6 +3439,7 @@ static const TypeInfo rtl8139_info = {
.instance_size = sizeof(RTL8139State),
.class_init = rtl8139_class_init,
.instance_init = rtl8139_instance_init,
+ .insecure = true,
.interfaces = (const InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ },
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
index 5cd78e334b..89c959234e 100644
--- a/hw/net/smc91c111.c
+++ b/hw/net/smc91c111.c
@@ -928,6 +928,7 @@ static const TypeInfo smc91c111_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(smc91c111_state),
.class_init = smc91c111_class_init,
+ .insecure = true,
};
static void smc91c111_register_types(void)
diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
index f6f217d632..07b8d125e5 100644
--- a/hw/net/spapr_llan.c
+++ b/hw/net/spapr_llan.c
@@ -873,6 +873,7 @@ static const TypeInfo spapr_vlan_info = {
.class_init = spapr_vlan_class_init,
.instance_init = spapr_vlan_instance_init,
.instance_finalize = spapr_vlan_instance_finalize,
+ .insecure = true,
};
static void spapr_vlan_register_types(void)
diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c
index 2fc51e1e16..cb29ba6e02 100644
--- a/hw/net/stellaris_enet.c
+++ b/hw/net/stellaris_enet.c
@@ -516,6 +516,7 @@ static const TypeInfo stellaris_enet_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(stellaris_enet_state),
.class_init = stellaris_enet_class_init,
+ .insecure = true,
};
static void stellaris_enet_register_types(void)
diff --git a/hw/net/sungem.c b/hw/net/sungem.c
index b405eb89fa..7ca0ab8d46 100644
--- a/hw/net/sungem.c
+++ b/hw/net/sungem.c
@@ -1477,6 +1477,7 @@ static const TypeInfo sungem_info = {
.instance_size = sizeof(SunGEMState),
.class_init = sungem_class_init,
.instance_init = sungem_instance_init,
+ .insecure = true,
.interfaces = (const InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ }
diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c
index c2f7a8483d..5d601395f3 100644
--- a/hw/net/sunhme.c
+++ b/hw/net/sunhme.c
@@ -958,6 +958,7 @@ static const TypeInfo sunhme_info = {
.class_init = sunhme_class_init,
.instance_size = sizeof(SunHMEState),
.instance_init = sunhme_instance_init,
+ .insecure = true,
.interfaces = (const InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ }
diff --git a/hw/net/tulip.c b/hw/net/tulip.c
index 319af906c8..4b1645bd27 100644
--- a/hw/net/tulip.c
+++ b/hw/net/tulip.c
@@ -1035,6 +1035,7 @@ static const TypeInfo tulip_info = {
.instance_size = sizeof(TULIPState),
.class_init = tulip_class_init,
.instance_init = tulip_instance_init,
+ .insecure = true,
.interfaces = (const InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ },
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 6b5b5dace3..b34c0f3afc 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -4259,6 +4259,7 @@ static const TypeInfo virtio_net_info = {
.instance_size = sizeof(VirtIONet),
.instance_init = virtio_net_instance_init,
.class_init = virtio_net_class_init,
+ .secure = true,
};
static void virtio_register_types(void)
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index af73aa8ef2..29b0efc1db 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -2491,6 +2491,7 @@ static const TypeInfo vmxnet3_info = {
.instance_size = sizeof(VMXNET3State),
.class_init = vmxnet3_class_init,
.instance_init = vmxnet3_instance_init,
+ .insecure = true,
.interfaces = (const InterfaceInfo[]) {
{ INTERFACE_PCIE_DEVICE },
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c
index 34c6a1d0b0..eae29b4407 100644
--- a/hw/net/xen_nic.c
+++ b/hw/net/xen_nic.c
@@ -581,6 +581,7 @@ static const TypeInfo xen_net_type_info = {
.parent = TYPE_XEN_DEVICE,
.instance_size = sizeof(XenNetDev),
.class_init = xen_netdev_class_init,
+ .secure = true,
};
static void xen_net_register_types(void)
diff --git a/hw/net/xgmac.c b/hw/net/xgmac.c
index d45f872467..1fa2361404 100644
--- a/hw/net/xgmac.c
+++ b/hw/net/xgmac.c
@@ -432,6 +432,7 @@ static const TypeInfo xgmac_enet_info = {
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(XgmacState),
.class_init = xgmac_enet_class_init,
+ .insecure = true,
};
static void xgmac_enet_register_types(void)
diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
index 1f5c748047..1e27bfff3d 100644
--- a/hw/net/xilinx_axienet.c
+++ b/hw/net/xilinx_axienet.c
@@ -1038,6 +1038,7 @@ static const TypeInfo xilinx_enet_info = {
.instance_size = sizeof(XilinxAXIEnet),
.class_init = xilinx_enet_class_init,
.instance_init = xilinx_enet_init,
+ .insecure = true,
};
static const TypeInfo xilinx_enet_data_stream_info = {
diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index 42b19d07c7..81ed721ad8 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -401,6 +401,7 @@ static const TypeInfo xilinx_ethlite_types[] = {
.instance_size = sizeof(XlnxXpsEthLite),
.instance_init = xilinx_ethlite_init,
.class_init = xilinx_ethlite_class_init,
+ .insecure = true,
},
};
--
2.50.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* [PATCH 15/15] docs: expand security docs with info about secure/insecure markers
2025-09-09 16:57 [PATCH <RFC> 00/15] Encode object type security status in code Daniel P. Berrangé
` (13 preceding siblings ...)
2025-09-09 16:57 ` [PATCH 14/15] hw/net: mark all NICs as insecure except e1000, e1000e & xen Daniel P. Berrangé
@ 2025-09-09 16:57 ` Daniel P. Berrangé
2025-09-16 16:43 ` [PATCH <RFC> 00/15] Encode object type security status in code Daniel P. Berrangé
2025-09-18 11:35 ` Markus Armbruster
16 siblings, 0 replies; 23+ messages in thread
From: Daniel P. Berrangé @ 2025-09-09 16:57 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, Paolo Bonzini, Peter Maydell, Stefan Hajnoczi,
Markus Armbruster, Thomas Huth, Daniel P. Berrangé
The explicit 'secure' or 'insecure' markers will take priority over
the general "virtualization" vs "non-virtualization" use case
classfication.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
---
docs/system/security.rst | 41 ++++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/docs/system/security.rst b/docs/system/security.rst
index f2092c8768..15cffc2685 100644
--- a/docs/system/security.rst
+++ b/docs/system/security.rst
@@ -49,6 +49,47 @@ Bugs affecting the non-virtualization use case are not considered security
bugs at this time. Users with non-virtualization use cases must not rely on
QEMU to provide guest isolation or any security guarantees.
+Security status reporting
+'''''''''''''''''''''''''
+
+QEMU is progressively working to annotate object types to explicitly state
+whether they are considered to provide a security boundary or not.
+
+When the `require-secure=yes` parameter is given to the `-machine` argument
+attempts to use any type which is not explicitly considered secure will
+result in an error.
+
+When the `prohibit-insecure=yes` parameter is given to the `-machine` argument
+attempts to use any type which is explicitly considered insecure will result
+in an error.
+
+This gives three effective levels of control over the security
+
+ * default: any type can be used
+ * `prohibit-insecure=yes`: only exclude explicitly insecure types, allow
+ those which have no security statement, or which are explicitly secure
+ * `require-secure=yes`: only allow explicitly secure types, exclude those
+ which have no security statement, or which are explicitly insecure
+
+Violations of the requested policy will result in QEMU preventing the launch
+of the VM, or preventing hot-add of the device in the monitor.
+
+When considering whether to treat a flaw as a security issue, the following
+criteria will be used
+
+ * Type marked 'secure': eligible for security process with embargo where
+ applicable
+ * Type marked 'insecure': ineligible for security process, will be triaged
+ on the public mailing list / bug trackers
+ * Type with no security statement: "Virtualization" vs "Non-Virtualization"
+ use case will be used as a guide to decide on handling process, evaluated
+ upon bug report
+
+Machine type security status can be queried using '-machine help' or the
+QMP 'query-machines' command.
+
+Device type security status can be queried using '-device help'.
+
Architecture
------------
--
2.50.1
^ permalink raw reply related [flat|nested] 23+ messages in thread* Re: [PATCH <RFC> 00/15] Encode object type security status in code
2025-09-09 16:57 [PATCH <RFC> 00/15] Encode object type security status in code Daniel P. Berrangé
` (14 preceding siblings ...)
2025-09-09 16:57 ` [PATCH 15/15] docs: expand security docs with info about secure/insecure markers Daniel P. Berrangé
@ 2025-09-16 16:43 ` Daniel P. Berrangé
2025-09-16 16:51 ` Peter Maydell
2025-09-18 11:35 ` Markus Armbruster
16 siblings, 1 reply; 23+ messages in thread
From: Daniel P. Berrangé @ 2025-09-16 16:43 UTC (permalink / raw)
To: qemu-devel
Cc: Michael S. Tsirkin, Paolo Bonzini, Peter Maydell, Stefan Hajnoczi,
Markus Armbruster, Thomas Huth
Ping: anyone have thoughts on this idea of annotating security
status of our code against QOM classes ?
On Tue, Sep 09, 2025 at 05:57:11PM +0100, Daniel P. Berrangé wrote:
> Our docs/system/security.rst file loosely classifies code into that
> applicable for 'virtualization' vs 'non-virtualization' use cases.
> Only code relevant to the former group is eligible for security
> bug handling. Peter's recent proposal pointed out that we are
> increasingly hitting the limits of such a crude classification:
>
> https://lists.nongnu.org/archive/html/qemu-devel/2025-09/msg01520.html
>
> Michael suggested that with the increased complexity, docs are not
> going to be an effective way to convey the information, and we
> need to re-consider embedding this info in code:
>
> https://lists.nongnu.org/archive/html/qemu-devel/2025-09/msg01566.html
>
> This also allows users to validate a configuration's security status
> when starting a guest, or modifying a running guest. This series is
> an attempt to start the embedding process.
>
> It starts with QOM, adding "bool secure" and "bool insecure"
> properties to the TypeInfo struct, which get turned into flags
> on the Type struct. This enables querying any ObjectClass to
> ask whether or not it is declared secure or insecure.
>
> By default no statement will be made about whether a class is
> secure or insecure, reflecting our historical defaults. Over
> time we should annotate as many classes as possible with an
> explicit statement.
>
> The "-machine" argument gains two new parameters
>
> * prohibit-insecure=yes|no - a weak security boundary, only
> excluding stuff that is explicitly declared insecure,
> permiting stuff that is secure & anything without a stetement
>
> * require-secure=yes|no - a strong security boundary, only
> permitting stuff that is explicitly declared secure,
> excluding insecure stuff & anything without a statement
>
> As illustration, I have added explicit annotations for many machine
> types, some accelerators, all NICs (all insecure except xen,
> e1000(e) and virtio), and all PCI virtio devices (all secure).
>
> Example: TCG is explicitly insecure, KVM is explicitly secure,
> qtest has no statement:
>
> $ qemu-system-x86_64 -display none -machine pc,prohibit-insecure=yes -accel tcg
> qemu-system-x86_64: Type 'tcg-accel' is declared as insecure
>
> $ qemu-system-x86_64 -display none -machine pc,require-secure=yes -accel tcg
> qemu-system-x86_64: Type 'tcg-accel' is not declared as secure
>
> $ qemu-system-x86_64 -display none -machine pc,prohibit-insecure=yes -accel kvm
> ^Cqemu-system-x86_64: terminating on signal 2
>
> $ qemu-system-x86_64 -display none -machine pc,require-secure=yes -accel kvm
> ^Cqemu-system-x86_64: terminating on signal 2
>
> $ qemu-system-x86_64 -display none -machine pc,prohibit-insecure=yes -accel qtest
> ^Cqemu-system-x86_64: terminating on signal 2
>
> $ qemu-system-x86_64 -display none -machine pc,require-secure=yes -accel qtest
> qemu-system-x86_64: Type 'qtest-accel' is not declared as secure
>
> Example: isapc machine type is explicitly insecure
>
> $ qemu-system-x86_64 -display none -machine isapc,require-secure=yes -accel kvm
> qemu-system-x86_64: Type 'isapc-machine' is not declared as secure
>
> Example: devices which have no security statement are allowed if
> merely excluding insecure devices:
>
> $ qemu-system-x86_64 -display none -machine pc,prohibit-insecure=yes -accel kvm -device i6300esb
> ^Cqemu-system-x86_64: terminating on signal 2
>
> Example: devices which have no security statement are rejected if
> requiring explicit security:
>
> $ qemu-system-x86_64 -display none -machine pc,require-secure=yes -accel kvm -device i6300esb
> qemu-system-x86_64: -device i6300esb: Type 'i6300esb' is not declared as secure
>
> Example: checks also apply in HMP, rtl8139 is explicitly insecure,
> virtio is explicitly secure
>
> $ qemu-system-x86_64 -display none -machine pc,require-secure=yes -accel kvm -monitor stdio
> QEMU 10.1.50 monitor - type 'help' for more information
> (qemu) device_add rtl8139
> Error: Type 'rtl8139' is not declared as secure
> (qemu) device_add virtio-net
>
> Example: checks also apply in QMP:
>
> $ ./scripts/qmp/qmp-shell-wrap qemu-system-x86_64 -display none -machine pc,require-secure=yes -accel kvm
> Welcome to the QMP low-level shell!
> Connected
> (QEMU) device_add driver=rtl8139
> {"error": {"class": "GenericError", "desc": "Type 'rtl8139' is not declared as secure"}}
> (QEMU) device_add driver=virtio-net
> {"return": {}}
>
> Some questions....
>
> * Is using '-machine' the right place to express the policy ?
>
> * Can we change '-accel help' to report 'secure' / 'insecure'
> as we did for '-machine help' and '-device help'.
>
> * Should we have 'query-devices' for QMP to allow the 'secure'
> or 'insecure' status to be queried for every device.
>
> * Should we have 'query-accel' for QMP to allow the 'secure'
> or 'insecure' status to be queried for every accelerator.
>
> * Should we enforce checks for -object & object_add too ?
> Easy to add code for this, but do we need the ability to
> exclude some object backends of dubious code quality ?
>
> * Likewise for -chardev / -netdev / etc which are
> conceptual specializations of -object
>
> * BlockDriver structs don't use QOM, so we can't mark
> 'vvfat' block backend as insecure
>
> The first one about '-machine' is probably the main blocker
> from a design POV. Other things are just potential future
> incremental work.
>
> This series has had only 1/2 a day's work / thought put into
> it, hence RFC status. It has been compiled and minimally tested
> with the examples shown above. I have not pushed this through
> CI nor considered tests yet. Still it gives a good illustration
> of what's involved in recording security info in code.
>
> Daniel P. Berrangé (15):
> qom: replace 'abstract' with 'flags'
> qom: add tracking of security state of object types
> machine: add 'require-secure' and 'prohibit-insecure' properties
> machine: check security for machine and accelerator types
> system: report machine security status in help output
> system: check security of device types
> system: report device security status in help output
> hw/core: report secure/insecure status in query-machines
> accel: mark 'kvm' as secure and 'tcg' as insecure
> hw/virtio: mark all virtio PCI devices as secure
> hw: mark x86, s390, ppc, arm versioned machine types as secure
> hw: declare Xen & microvm machines as secure, isapc as insecure
> hw/core: declare 'none' machine to be insecure
> hw/net: mark all NICs as insecure except e1000, e1000e & xen
> docs: expand security docs with info about secure/insecure markers
>
> accel/kvm/kvm-all.c | 1 +
> accel/tcg/tcg-all.c | 1 +
> docs/system/security.rst | 41 +++++++++++++++++++++
> hw/arm/virt.c | 1 +
> hw/arm/xen-pvh.c | 1 +
> hw/core/machine-qmp-cmds.c | 2 ++
> hw/core/machine.c | 66 ++++++++++++++++++++++++++++++++++
> hw/core/null-machine.c | 2 +-
> hw/i386/isapc.c | 2 +-
> hw/i386/microvm.c | 1 +
> hw/i386/pc_piix.c | 4 +--
> hw/i386/xen/xen-pvh.c | 1 +
> hw/i386/xen/xen_pvdevice.c | 1 +
> hw/net/allwinner-sun8i-emac.c | 1 +
> hw/net/allwinner_emac.c | 3 +-
> hw/net/cadence_gem.c | 1 +
> hw/net/can/can_kvaser_pci.c | 1 +
> hw/net/can/can_mioe3680_pci.c | 1 +
> hw/net/can/can_pcm3680_pci.c | 1 +
> hw/net/can/ctucan_pci.c | 1 +
> hw/net/can/xlnx-versal-canfd.c | 1 +
> hw/net/can/xlnx-zynqmp-can.c | 1 +
> hw/net/dp8393x.c | 1 +
> hw/net/e1000.c | 1 +
> hw/net/e1000e.c | 1 +
> hw/net/eepro100.c | 1 +
> hw/net/fsl_etsec/etsec.c | 1 +
> hw/net/ftgmac100.c | 1 +
> hw/net/igb.c | 1 +
> hw/net/igbvf.c | 1 +
> hw/net/imx_fec.c | 2 ++
> hw/net/lan9118.c | 1 +
> hw/net/lan9118_phy.c | 1 +
> hw/net/lance.c | 1 +
> hw/net/lasi_i82596.c | 1 +
> hw/net/mcf_fec.c | 1 +
> hw/net/msf2-emac.c | 1 +
> hw/net/mv88w8618_eth.c | 1 +
> hw/net/ne2000-isa.c | 1 +
> hw/net/ne2000-pci.c | 1 +
> hw/net/npcm7xx_emc.c | 1 +
> hw/net/npcm_gmac.c | 1 +
> hw/net/npcm_pcs.c | 1 +
> hw/net/opencores_eth.c | 1 +
> hw/net/pcnet-pci.c | 1 +
> hw/net/rocker/rocker.c | 1 +
> hw/net/rtl8139.c | 1 +
> hw/net/smc91c111.c | 1 +
> hw/net/spapr_llan.c | 1 +
> hw/net/stellaris_enet.c | 1 +
> hw/net/sungem.c | 1 +
> hw/net/sunhme.c | 1 +
> hw/net/tulip.c | 1 +
> hw/net/virtio-net.c | 1 +
> hw/net/vmxnet3.c | 1 +
> hw/net/xen_nic.c | 1 +
> hw/net/xgmac.c | 1 +
> hw/net/xilinx_axienet.c | 1 +
> hw/net/xilinx_ethlite.c | 1 +
> hw/ppc/spapr.c | 1 +
> hw/s390x/s390-virtio-ccw.c | 1 +
> hw/virtio/virtio-pci.c | 3 ++
> hw/xen/xen-pvh-common.c | 1 +
> hw/xenpv/xen_machine_pv.c | 2 +-
> include/hw/boards.h | 18 +++++++++-
> include/hw/i386/pc.h | 5 ++-
> include/qom/object.h | 24 +++++++++++++
> qapi/machine.json | 9 ++++-
> qom/object.c | 40 +++++++++++++++++----
> system/qdev-monitor.c | 10 ++++++
> system/vl.c | 6 ++--
> 71 files changed, 275 insertions(+), 18 deletions(-)
>
> --
> 2.50.1
>
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 23+ messages in thread* Re: [PATCH <RFC> 00/15] Encode object type security status in code
2025-09-09 16:57 [PATCH <RFC> 00/15] Encode object type security status in code Daniel P. Berrangé
` (15 preceding siblings ...)
2025-09-16 16:43 ` [PATCH <RFC> 00/15] Encode object type security status in code Daniel P. Berrangé
@ 2025-09-18 11:35 ` Markus Armbruster
2025-09-18 12:29 ` Daniel P. Berrangé
16 siblings, 1 reply; 23+ messages in thread
From: Markus Armbruster @ 2025-09-18 11:35 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: qemu-devel, Michael S. Tsirkin, Paolo Bonzini, Peter Maydell,
Stefan Hajnoczi, Thomas Huth
Daniel P. Berrangé <berrange@redhat.com> writes:
> Our docs/system/security.rst file loosely classifies code into that
> applicable for 'virtualization' vs 'non-virtualization' use cases.
> Only code relevant to the former group is eligible for security
> bug handling. Peter's recent proposal pointed out that we are
> increasingly hitting the limits of such a crude classification:
>
> https://lists.nongnu.org/archive/html/qemu-devel/2025-09/msg01520.html
Yes, we do.
> Michael suggested that with the increased complexity, docs are not
> going to be an effective way to convey the information, and we
> need to re-consider embedding this info in code:
>
> https://lists.nongnu.org/archive/html/qemu-devel/2025-09/msg01566.html
>
> This also allows users to validate a configuration's security status
> when starting a guest, or modifying a running guest. This series is
> an attempt to start the embedding process.
I like the idea.
We have a long list of configuration choices that might / are known to
punch holes into security boundaries. Documenting them is entirely
inadequate; telling users who got p0wned it's their own fault for having
missed this particlar drop in the sea of QEMU documentation reminds me
of Douglas Adams' “Beware of The Leopard“.
And we don't have even that! Just handwavy talk about a "virtualization
use case".
We can and should do better.
> It starts with QOM, adding "bool secure" and "bool insecure"
> properties to the TypeInfo struct, which get turned into flags
> on the Type struct. This enables querying any ObjectClass to
> ask whether or not it is declared secure or insecure.
We should clearly document what "declared secure" actually means.
Here's my attempt at it: supported for use cases that require certain
security boundaries.
> By default no statement will be made about whether a class is
> secure or insecure, reflecting our historical defaults. Over
> time we should annotate as many classes as possible with an
> explicit statement.
>
> The "-machine" argument gains two new parameters
>
> * prohibit-insecure=yes|no - a weak security boundary, only
> excluding stuff that is explicitly declared insecure,
> permiting stuff that is secure & anything without a stetement
This isn't what users need.
> * require-secure=yes|no - a strong security boundary, only
> permitting stuff that is explicitly declared secure,
> excluding insecure stuff & anything without a statement
This would be, if it covered everything accessible at the security
boundaries. It doesn't for now: only QOM.
It might still be better than nothing.
However, it may well be unusable until enough of QOM is declared secure.
What would our advice to users be? I'm afraid something complicated and
impermanent like "try require-secure=yes, and if you can't make it work
because parts of QOM you can't do without are still undeclared, fall
back to prohibit-insecure=yes, and be aware this avoids only some, but
not all security boundary death traps in either case."
This is an awful user interface. But it's also a step towards the user
interface we want: a single, unchanging switch that ensures you're
running something that's fully supported for use cases that require
certain security boundaries.
A next step could be getting enough of QOM declared so we can move to a
single switch, with the (hopefully temporary) caveat about "only QOM".
We should clearly and prominently document the limitations at each step.
> As illustration, I have added explicit annotations for many machine
> types, some accelerators, all NICs (all insecure except xen,
> e1000(e) and virtio), and all PCI virtio devices (all secure).
>
> Example: TCG is explicitly insecure, KVM is explicitly secure,
> qtest has no statement:
>
> $ qemu-system-x86_64 -display none -machine pc,prohibit-insecure=yes -accel tcg
> qemu-system-x86_64: Type 'tcg-accel' is declared as insecure
[...]
> Some questions....
>
> * Is using '-machine' the right place to express the policy ?
Not sure. The guest boundary is just one of several security boundaries
listed in docs/system/security.rst. Some of them aren't really about
the guest / the machine.
Maybe -compat? It lets you exclude unstable or deprecated bits from the
user interface. Feels similar to excluding insecure bits.
> * Can we change '-accel help' to report 'secure' / 'insecure'
> as we did for '-machine help' and '-device help'.
No idea, guess it's at worst a matter of shaving the yak?
> * Should we have 'query-devices' for QMP to allow the 'secure'
> or 'insecure' status to be queried for every device.
>
> * Should we have 'query-accel' for QMP to allow the 'secure'
> or 'insecure' status to be queried for every accelerator.
I recommend qom-list-types. Covers all of QOM, not just devices and
accelerators.
> * Should we enforce checks for -object & object_add too ?
> Easy to add code for this, but do we need the ability to
> exclude some object backends of dubious code quality ?
>
> * Likewise for -chardev / -netdev / etc which are
> conceptual specializations of -object
I lean towards all of QOM, no ifs, no buts.
> * BlockDriver structs don't use QOM, so we can't mark
> 'vvfat' block backend as insecure
I think this is the biggest gap.
> The first one about '-machine' is probably the main blocker
> from a design POV. Other things are just potential future
> incremental work.
>
> This series has had only 1/2 a day's work / thought put into
> it, hence RFC status. It has been compiled and minimally tested
> with the examples shown above. I have not pushed this through
> CI nor considered tests yet. Still it gives a good illustration
> of what's involved in recording security info in code.
Thanks for that!
^ permalink raw reply [flat|nested] 23+ messages in thread* Re: [PATCH <RFC> 00/15] Encode object type security status in code
2025-09-18 11:35 ` Markus Armbruster
@ 2025-09-18 12:29 ` Daniel P. Berrangé
2025-09-18 14:44 ` Markus Armbruster
0 siblings, 1 reply; 23+ messages in thread
From: Daniel P. Berrangé @ 2025-09-18 12:29 UTC (permalink / raw)
To: Markus Armbruster
Cc: qemu-devel, Michael S. Tsirkin, Paolo Bonzini, Peter Maydell,
Stefan Hajnoczi, Thomas Huth
On Thu, Sep 18, 2025 at 01:35:56PM +0200, Markus Armbruster wrote:
> Daniel P. Berrangé <berrange@redhat.com> writes:
> > It starts with QOM, adding "bool secure" and "bool insecure"
> > properties to the TypeInfo struct, which get turned into flags
> > on the Type struct. This enables querying any ObjectClass to
> > ask whether or not it is declared secure or insecure.
>
> We should clearly document what "declared secure" actually means.
> Here's my attempt at it: supported for use cases that require certain
> security boundaries.
>
> > By default no statement will be made about whether a class is
> > secure or insecure, reflecting our historical defaults. Over
> > time we should annotate as many classes as possible with an
> > explicit statement.
> >
> > The "-machine" argument gains two new parameters
> >
> > * prohibit-insecure=yes|no - a weak security boundary, only
> > excluding stuff that is explicitly declared insecure,
> > permiting stuff that is secure & anything without a stetement
>
> This isn't what users need.
>
> > * require-secure=yes|no - a strong security boundary, only
> > permitting stuff that is explicitly declared secure,
> > excluding insecure stuff & anything without a statement
>
> This would be, if it covered everything accessible at the security
> boundaries. It doesn't for now: only QOM.
>
> It might still be better than nothing.
>
> However, it may well be unusable until enough of QOM is declared secure.
Right, the problem is that for a while we'll have 3 buckets of
stuff (insecure, secure and "not sure yet"), when ideally we would
only have two buckets (insecure, secure).
I agree that for people running VMs, ideally require-secure=yes is
what they should be using.
The "not sure yet" bucket is a bit like schrodinger's cat in a box.
If we only had require-secure=yes, and that was insufficient for
the user, they'd be left with no way to exclude stuff that is
/definitely/ insecure. The prohibit-insecure=yes is at least
telling them they're not using something that is a terribly
bad idea.
In practice most of the stuff in the 'not sure yet' bucket will
be stuff that you'll only want to use in combniation with TCG,
and thus your VM will be in the 'insecure' bucket anyway.
There is a 2nd less critical use case for prohibit-insecure=yes
in relation to security report triage.
If someone submits a security report and it relies on a config
that is blocked by prohibit-insecure=yes, then we can categorically
declare it out of scope for CVE handling.
Similarly the require-secure=yes is categorically in-scope.
The 'do not bucket' is where we have to do case-by-case
analysis of the reoprt to decide whether it is in scope or
not.
> What would our advice to users be? I'm afraid something complicated and
> impermanent like "try require-secure=yes, and if you can't make it work
> because parts of QOM you can't do without are still undeclared, fall
> back to prohibit-insecure=yes, and be aware this avoids only some, but
> not all security boundary death traps in either case."
>
> This is an awful user interface. But it's also a step towards the user
> interface we want: a single, unchanging switch that ensures you're
> running something that's fully supported for use cases that require
> certain security boundaries.
>
> A next step could be getting enough of QOM declared so we can move to a
> single switch, with the (hopefully temporary) caveat about "only QOM".
Maybe the right answer is to just declare everything insecure
by default and focus on just annotating stuff for the secure
bucket as quickly as possible.
The lazy option would be to take everything that is built in
a RHEL distro build and label it as secure. We know Red Hat
is already on the hook for fixing CVEs in any such component
and sending fixes upstream. So by following the RHEL allow
list initially we should be implying any new burden for the
upstream.
That would enable require-secure=yes for a useful amount of
code needed for secure KVM guests on x86, s390x, aarch64,
ppc64 and perhaps riscv.
> > Some questions....
> >
> > * Is using '-machine' the right place to express the policy ?
>
> Not sure. The guest boundary is just one of several security boundaries
> listed in docs/system/security.rst. Some of them aren't really about
> the guest / the machine.
>
> Maybe -compat? It lets you exclude unstable or deprecated bits from the
> user interface. Feels similar to excluding insecure bits.
Oh I forgot about -compat entirely. That does indeed feel like
a better place.
> > * Can we change '-accel help' to report 'secure' / 'insecure'
> > as we did for '-machine help' and '-device help'.
>
> No idea, guess it's at worst a matter of shaving the yak?
>
> > * Should we have 'query-devices' for QMP to allow the 'secure'
> > or 'insecure' status to be queried for every device.
> >
> > * Should we have 'query-accel' for QMP to allow the 'secure'
> > or 'insecure' status to be queried for every accelerator.
>
> I recommend qom-list-types. Covers all of QOM, not just devices and
> accelerators.
Yep that works, and is already reporting the 'abstract' property
so putting a'secure' property alongside fits nicely.
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH <RFC> 00/15] Encode object type security status in code
2025-09-18 12:29 ` Daniel P. Berrangé
@ 2025-09-18 14:44 ` Markus Armbruster
2025-09-18 14:51 ` Daniel P. Berrangé
0 siblings, 1 reply; 23+ messages in thread
From: Markus Armbruster @ 2025-09-18 14:44 UTC (permalink / raw)
To: Daniel P. Berrangé
Cc: Markus Armbruster, qemu-devel, Michael S. Tsirkin, Paolo Bonzini,
Peter Maydell, Stefan Hajnoczi, Thomas Huth
Daniel P. Berrangé <berrange@redhat.com> writes:
> On Thu, Sep 18, 2025 at 01:35:56PM +0200, Markus Armbruster wrote:
>> Daniel P. Berrangé <berrange@redhat.com> writes:
>
>> > It starts with QOM, adding "bool secure" and "bool insecure"
>> > properties to the TypeInfo struct, which get turned into flags
>> > on the Type struct. This enables querying any ObjectClass to
>> > ask whether or not it is declared secure or insecure.
>>
>> We should clearly document what "declared secure" actually means.
>> Here's my attempt at it: supported for use cases that require certain
>> security boundaries.
>
>
>
>>
>> > By default no statement will be made about whether a class is
>> > secure or insecure, reflecting our historical defaults. Over
>> > time we should annotate as many classes as possible with an
>> > explicit statement.
>> >
>> > The "-machine" argument gains two new parameters
>> >
>> > * prohibit-insecure=yes|no - a weak security boundary, only
>> > excluding stuff that is explicitly declared insecure,
>> > permiting stuff that is secure & anything without a stetement
>>
>> This isn't what users need.
>>
>> > * require-secure=yes|no - a strong security boundary, only
>> > permitting stuff that is explicitly declared secure,
>> > excluding insecure stuff & anything without a statement
>>
>> This would be, if it covered everything accessible at the security
>> boundaries. It doesn't for now: only QOM.
>>
>> It might still be better than nothing.
>>
>> However, it may well be unusable until enough of QOM is declared secure.
>
> Right, the problem is that for a while we'll have 3 buckets of
> stuff (insecure, secure and "not sure yet"), when ideally we would
> only have two buckets (insecure, secure).
>
> I agree that for people running VMs, ideally require-secure=yes is
> what they should be using.
>
> The "not sure yet" bucket is a bit like schrodinger's cat in a box.
>
> If we only had require-secure=yes, and that was insufficient for
> the user, they'd be left with no way to exclude stuff that is
> /definitely/ insecure.
Yes. I mentioned this fallback below.
> The prohibit-insecure=yes is at least
> telling them they're not using something that is a terribly
> bad idea.
It rules out known bad, but not "maybe terribly bad, we just don't
know".
> In practice most of the stuff in the 'not sure yet' bucket will
> be stuff that you'll only want to use in combniation with TCG,
> and thus your VM will be in the 'insecure' bucket anyway.
>
> There is a 2nd less critical use case for prohibit-insecure=yes
> in relation to security report triage.
>
> If someone submits a security report and it relies on a config
> that is blocked by prohibit-insecure=yes, then we can categorically
> declare it out of scope for CVE handling.
>
> Similarly the require-secure=yes is categorically in-scope.
>
> The 'do not bucket' is where we have to do case-by-case
> analysis of the reoprt to decide whether it is in scope or
> not.
Yes.
By the way, two booleans is a rather awkward encoding of three states.
What about require-secure=yes/no/feeling-lucky? We may want something
better than feeling-lucky, it's merely the first one that crossed my
mind :)
>> What would our advice to users be? I'm afraid something complicated and
>> impermanent like "try require-secure=yes, and if you can't make it work
>> because parts of QOM you can't do without are still undeclared, fall
>> back to prohibit-insecure=yes, and be aware this avoids only some, but
>> not all security boundary death traps in either case."
>>
>> This is an awful user interface. But it's also a step towards the user
>> interface we want: a single, unchanging switch that ensures you're
>> running something that's fully supported for use cases that require
>> certain security boundaries.
>>
>> A next step could be getting enough of QOM declared so we can move to a
>> single switch, with the (hopefully temporary) caveat about "only QOM".
>
> Maybe the right answer is to just declare everything insecure
> by default and focus on just annotating stuff for the secure
> bucket as quickly as possible.
Annotating something as known insecure has value, but we can do that
even with just one flag:
.secure = true;
means "declared secure",
.secure = false;
means "declared insecure", and nothing means "undecided".
Initializing .secure = false doesn't *do* anything (false is the
default), but it would still be a fine way to annotate.
> The lazy option would be to take everything that is built in
> a RHEL distro build and label it as secure. We know Red Hat
> is already on the hook for fixing CVEs in any such component
> and sending fixes upstream. So by following the RHEL allow
> list initially we should be implying any new burden for the
> upstream.
Do you mean no new burden?
> That would enable require-secure=yes for a useful amount of
> code needed for secure KVM guests on x86, s390x, aarch64,
> ppc64 and perhaps riscv.
[...]
^ permalink raw reply [flat|nested] 23+ messages in thread* Re: [PATCH <RFC> 00/15] Encode object type security status in code
2025-09-18 14:44 ` Markus Armbruster
@ 2025-09-18 14:51 ` Daniel P. Berrangé
0 siblings, 0 replies; 23+ messages in thread
From: Daniel P. Berrangé @ 2025-09-18 14:51 UTC (permalink / raw)
To: Markus Armbruster
Cc: qemu-devel, Michael S. Tsirkin, Paolo Bonzini, Peter Maydell,
Stefan Hajnoczi, Thomas Huth
On Thu, Sep 18, 2025 at 04:44:31PM +0200, Markus Armbruster wrote:
> Daniel P. Berrangé <berrange@redhat.com> writes:
>
> > On Thu, Sep 18, 2025 at 01:35:56PM +0200, Markus Armbruster wrote:
> >> Daniel P. Berrangé <berrange@redhat.com> writes:
> >
> >> > It starts with QOM, adding "bool secure" and "bool insecure"
> >> > properties to the TypeInfo struct, which get turned into flags
> >> > on the Type struct. This enables querying any ObjectClass to
> >> > ask whether or not it is declared secure or insecure.
> >>
> >> We should clearly document what "declared secure" actually means.
> >> Here's my attempt at it: supported for use cases that require certain
> >> security boundaries.
> >
> >
> >
> >>
> >> > By default no statement will be made about whether a class is
> >> > secure or insecure, reflecting our historical defaults. Over
> >> > time we should annotate as many classes as possible with an
> >> > explicit statement.
> >> >
> >> > The "-machine" argument gains two new parameters
> >> >
> >> > * prohibit-insecure=yes|no - a weak security boundary, only
> >> > excluding stuff that is explicitly declared insecure,
> >> > permiting stuff that is secure & anything without a stetement
> >>
> >> This isn't what users need.
> >>
> >> > * require-secure=yes|no - a strong security boundary, only
> >> > permitting stuff that is explicitly declared secure,
> >> > excluding insecure stuff & anything without a statement
>
> By the way, two booleans is a rather awkward encoding of three states.
> What about require-secure=yes/no/feeling-lucky? We may want something
> better than feeling-lucky, it's merely the first one that crossed my
> mind :)
Yeah, this is mostly me being lazy - by the time I realized that
an enum would have been better, I didn't want to rewrite it, so I
just sent this RFC as is.
> >> What would our advice to users be? I'm afraid something complicated and
> >> impermanent like "try require-secure=yes, and if you can't make it work
> >> because parts of QOM you can't do without are still undeclared, fall
> >> back to prohibit-insecure=yes, and be aware this avoids only some, but
> >> not all security boundary death traps in either case."
> >>
> >> This is an awful user interface. But it's also a step towards the user
> >> interface we want: a single, unchanging switch that ensures you're
> >> running something that's fully supported for use cases that require
> >> certain security boundaries.
> >>
> >> A next step could be getting enough of QOM declared so we can move to a
> >> single switch, with the (hopefully temporary) caveat about "only QOM".
> >
> > Maybe the right answer is to just declare everything insecure
> > by default and focus on just annotating stuff for the secure
> > bucket as quickly as possible.
>
> Annotating something as known insecure has value, but we can do that
> even with just one flag:
>
> .secure = true;
>
> means "declared secure",
>
> .secure = false;
>
> means "declared insecure", and nothing means "undecided".
>
> Initializing .secure = false doesn't *do* anything (false is the
> default), but it would still be a fine way to annotate.
I'm fine with that, as long as we don't need to be able to
programmatically query that distinction. From an external
view, '= false' and <unset> would be undistinguishable
and both be considered 'insecure'.
It would mean we, as maintainers, would know what files
are yet to be evaluated for their security status which
is still useful.
>
> > The lazy option would be to take everything that is built in
> > a RHEL distro build and label it as secure. We know Red Hat
> > is already on the hook for fixing CVEs in any such component
> > and sending fixes upstream. So by following the RHEL allow
> > list initially we should be implying any new burden for the
> > upstream.
>
> Do you mean no new burden?
Sigh, yes. No new burden.
>
> > That would enable require-secure=yes for a useful amount of
> > code needed for secure KVM guests on x86, s390x, aarch64,
> > ppc64 and perhaps riscv.
>
> [...]
>
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
^ permalink raw reply [flat|nested] 23+ messages in thread