[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC PATCH v4 06/20] core: add new security-policy object
From: |
Brijesh Singh |
Subject: |
[Qemu-devel] [RFC PATCH v4 06/20] core: add new security-policy object |
Date: |
Wed, 8 Mar 2017 15:52:09 -0500 |
User-agent: |
StGit/0.17.1-dirty |
The object can be used to define global security policy for the guest.
object provides two properties:
1) debug: can be used to disable guest memory access from hypervisor.
e.g to disable guest memory debug accesses
# $QEMU \
-object security-policy,debug=false,id=mypolicy \
-machine ...,security-policy=mypolicy
2) memory-encryption: if hypervisor supports memory encryption then this
property can be used to define object for encryption.
# $QEMU \
-object sev-guest,id=sev0 \
-object security-policy,id=memory-encryption=sev0,id=mypolicy \
-machine ...,security-policy=mypolicy
The memory-encryption property will be used for enabling AMD's SEV feature.
Signed-off-by: Brijesh Singh <address@hidden>
---
exec.c | 7 ++
hw/core/Makefile.objs | 1
hw/core/machine.c | 22 +++++
hw/core/security-policy.c | 165 ++++++++++++++++++++++++++++++++++++++
include/hw/boards.h | 1
include/sysemu/security-policy.h | 75 +++++++++++++++++
qemu-options.hx | 21 +++++
7 files changed, 292 insertions(+)
create mode 100644 hw/core/security-policy.c
create mode 100644 include/sysemu/security-policy.h
diff --git a/exec.c b/exec.c
index 772a959..2c7c891 100644
--- a/exec.c
+++ b/exec.c
@@ -40,6 +40,7 @@
#else /* !CONFIG_USER_ONLY */
#include "hw/hw.h"
#include "exec/memory.h"
+#include "sysemu/security-policy.h"
#include "exec/ioport.h"
#include "sysemu/dma.h"
#include "sysemu/numa.h"
@@ -2926,6 +2927,12 @@ static inline void
cpu_physical_memory_rw_debug_internal(AddressSpace *as,
hwaddr addr1;
MemoryRegion *mr;
+ /* Check if debug accesses is allowed */
+ if (attrs.debug &&
+ !security_policy_debug_allowed(current_machine->security_policy)) {
+ return;
+ }
+
rcu_read_lock();
while (len > 0) {
l = len;
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index 91450b2..3c413b1 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -18,6 +18,7 @@ common-obj-$(CONFIG_SOFTMMU) += qdev-properties-system.o
common-obj-$(CONFIG_SOFTMMU) += register.o
common-obj-$(CONFIG_SOFTMMU) += or-irq.o
common-obj-$(CONFIG_PLATFORM_BUS) += platform-bus.o
+common-obj-$(CONFIG_SOFTMMU) += security-policy.o
obj-$(CONFIG_SOFTMMU) += generic-loader.o
obj-$(CONFIG_SOFTMMU) += null-machine.o
diff --git a/hw/core/machine.c b/hw/core/machine.c
index 0699750..c14f59c 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -332,6 +332,23 @@ static bool machine_get_enforce_config_section(Object
*obj, Error **errp)
return ms->enforce_config_section;
}
+static char *machine_get_security_policy(Object *obj, Error **errp)
+{
+ MachineState *ms = MACHINE(obj);
+
+ return g_strdup(ms->security_policy);
+}
+
+static void machine_set_security_policy(Object *obj,
+ const char *value, Error **errp)
+{
+ MachineState *ms = MACHINE(obj);
+
+ g_free(ms->security_policy);
+ ms->security_policy = g_strdup(value);
+}
+
+
static void error_on_sysbus_device(SysBusDevice *sbdev, void *opaque)
{
error_report("Option '-device %s' cannot be handled by this machine",
@@ -493,6 +510,11 @@ static void machine_class_init(ObjectClass *oc, void *data)
&error_abort);
object_class_property_set_description(oc, "enforce-config-section",
"Set on to enforce configuration section migration", &error_abort);
+
+ object_class_property_add_str(oc, "security-policy",
+ machine_get_security_policy, machine_set_security_policy, NULL);
+ object_class_property_set_description(oc, "security-policy",
+ "Set the security policy for the machine", NULL);
}
static void machine_class_base_init(ObjectClass *oc, void *data)
diff --git a/hw/core/security-policy.c b/hw/core/security-policy.c
new file mode 100644
index 0000000..4d4658e
--- /dev/null
+++ b/hw/core/security-policy.c
@@ -0,0 +1,165 @@
+/*
+ * QEMU security policy support
+ *
+ * Copyright (c) 2016 Advanced Micro Devices
+ *
+ * Author:
+ * Brijesh Singh <address@hidden>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "qom/object_interfaces.h"
+#include "qemu/base64.h"
+
+#include "sysemu/security-policy.h"
+
+static SecurityPolicy *
+find_security_policy_obj(const char *name)
+{
+ Object *obj;
+ SecurityPolicy *policy;
+
+ if (!name) {
+ return NULL;
+ }
+
+ obj = object_resolve_path_component(
+ object_get_objects_root(), name);
+ if (!obj) {
+ return NULL;
+ }
+
+ policy = (SecurityPolicy *)
+ object_dynamic_cast(obj,
+ TYPE_SECURITY_POLICY);
+ if (!policy) {
+ return NULL;
+ }
+
+ return policy;
+}
+
+bool
+security_policy_debug_allowed(const char *secure_policy_id)
+{
+ SecurityPolicy *policy = find_security_policy_obj(secure_policy_id);
+
+ /* if id is not a valid security policy then we return true */
+ return policy ? policy->debug : true;
+}
+
+char *
+security_policy_get_memory_encryption_id(const char *secure_policy_id)
+{
+ SecurityPolicy *policy = find_security_policy_obj(secure_policy_id);
+
+ return policy ? g_strdup(policy->memory_encryption) : NULL;
+}
+
+static bool
+security_policy_prop_get_debug(Object *obj,
+ Error **errp G_GNUC_UNUSED)
+{
+ SecurityPolicy *policy = SECURITY_POLICY(obj);
+
+ return policy->debug;
+}
+
+
+static void
+security_policy_prop_set_debug(Object *obj,
+ bool value,
+ Error **errp G_GNUC_UNUSED)
+{
+ SecurityPolicy *policy = SECURITY_POLICY(obj);
+
+ policy->debug = value;
+}
+
+static char *
+sev_launch_get_memory_encryption(Object *obj, Error **errp)
+{
+ SecurityPolicy *policy = SECURITY_POLICY(obj);
+
+ return g_strdup(policy->memory_encryption);
+}
+
+static void
+sev_launch_set_memory_encryption(Object *obj, const char *value,
+ Error **errp)
+{
+ SecurityPolicy *policy = SECURITY_POLICY(obj);
+
+ policy->memory_encryption = g_strdup(value);
+}
+
+static void
+security_policy_init(Object *obj)
+{
+ SecurityPolicy *policy = SECURITY_POLICY(obj);
+
+ policy->debug = true;
+}
+
+static void
+security_policy_finalize(Object *obj)
+{
+}
+
+static void
+security_policy_class_init(ObjectClass *oc, void *data)
+{
+ object_class_property_add_bool(oc, "debug",
+ security_policy_prop_get_debug,
+ security_policy_prop_set_debug,
+ NULL);
+ object_class_property_set_description(oc, "debug",
+ "Set on/off if debugging is allowed on this guest (default on)",
+ NULL);
+ object_class_property_add_str(oc, "memory-encryption",
+ sev_launch_get_memory_encryption,
+ sev_launch_set_memory_encryption,
+ NULL);
+ object_class_property_set_description(oc, "memory-encryption",
+ "Set memory encryption object id (if supported by hardware)",
+ NULL);
+}
+
+static const TypeInfo security_policy_info = {
+ .parent = TYPE_OBJECT,
+ .name = TYPE_SECURITY_POLICY,
+ .instance_size = sizeof(SecurityPolicy),
+ .instance_init = security_policy_init,
+ .instance_finalize = security_policy_finalize,
+ .class_size = sizeof(SecurityPolicyClass),
+ .class_init = security_policy_class_init,
+ .interfaces = (InterfaceInfo[]) {
+ { TYPE_USER_CREATABLE },
+ { }
+ }
+};
+
+
+static void
+security_policy_register_types(void)
+{
+ type_register_static(&security_policy_info);
+}
+
+
+type_init(security_policy_register_types);
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 269d0ba..a1c99a0 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -153,6 +153,7 @@ struct MachineState {
/*< public >*/
char *accel;
+ char *security_policy;
bool kernel_irqchip_allowed;
bool kernel_irqchip_required;
bool kernel_irqchip_split;
diff --git a/include/sysemu/security-policy.h b/include/sysemu/security-policy.h
new file mode 100644
index 0000000..6d3789d
--- /dev/null
+++ b/include/sysemu/security-policy.h
@@ -0,0 +1,75 @@
+/*
+ * QEMU security policy support
+ *
+ * Copyright (c) 2016 Advanced Micro Devices
+ *
+ * Author:
+ * Brijesh Singh <address@hidden>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef SECURITY_POLICY_H
+#define SECURITY_POLICY_H
+
+#include "qom/object.h"
+
+#define TYPE_SECURITY_POLICY "security-policy"
+#define SECURITY_POLICY(obj) \
+ OBJECT_CHECK(SecurityPolicy, (obj), TYPE_SECURITY_POLICY)
+
+typedef struct SecurityPolicy SecurityPolicy;
+typedef struct SecurityPolicyClass SecurityPolicyClass;
+
+/**
+ * SecurityPolicy:
+ *
+ * The SecurityPolicy object provides method to define
+ * various security releated policies for guest machine.
+ *
+ * e.g
+ * When launching QEMU, user can create a security policy
+ * to disallow memory dump and debug of guest
+ *
+ * # $QEMU \
+ * -object security-policy,id=mypolicy,debug=off \
+ * -machine ...,security-policy=mypolicy
+ *
+ * If hardware supports memory encryption then user can set
+ * encryption policy of guest
+ *
+ * # $QEMU \
+ * -object encrypt-policy,key=xxx,flags=xxxx,id=encrypt \
+ * -object security-policy,debug=off,memory-encryption=encrypt,id=mypolicy \
+ * -machine ...,security-policy=mypolicy
+ *
+ */
+
+struct SecurityPolicy {
+ Object parent_obj;
+
+ bool debug;
+ char *memory_encryption;
+};
+
+
+struct SecurityPolicyClass {
+ ObjectClass parent_class;
+};
+
+bool security_policy_debug_allowed(const char *name);
+char *security_policy_get_memory_encryption_id(const char *name);
+
+#endif /* SECURITY_POLICY_H */
diff --git a/qemu-options.hx b/qemu-options.hx
index 2292438..536db1b 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -4140,6 +4140,27 @@ contents of @code{iv.b64} to the second secret
@end table
address@hidden -object
security-policy,address@hidden,address@hidden,address@hidden
+
+Create a security policy object, which can be used to define guest security.
+The id parameter is a unique ID that will be used to reference this
+object when security-policy is applied via -machine argument.
+
+The 'debug' parameter can be defined to tell whether the debugging or memory
+dump is allowed through qemu monitor console.
+
+e.g to disable the guest memory dump
address@hidden
+ # $QEMU \
+ -object security-policy,id=secure0,debug=off \
+ -machine ...,security-policy=secure0
address@hidden example
+
+if hardware support guest memory encrytion, then 'memory-encryption' parameter
+can be set to the unquie ID of memory encryption object.
+
+On AMD processor, memory encryption is supported via 'sev-guest' object.
+
ETEXI
- [Qemu-devel] [RFC PATCH v4 02/20] memattrs: add debug attribute, (continued)
[Qemu-devel] [RFC PATCH v4 04/20] exec: add debug version of physical memory read and write api, Brijesh Singh, 2017/03/08
[Qemu-devel] [RFC PATCH v4 05/20] monitor/i386: use debug apis when accessing guest memory, Brijesh Singh, 2017/03/08
[Qemu-devel] [RFC PATCH v4 01/20] kvm: update kvm.h header file, Brijesh Singh, 2017/03/08
[Qemu-devel] [RFC PATCH v4 08/20] sev: add Secure Encrypted Virtulization (SEV) support, Brijesh Singh, 2017/03/08
[Qemu-devel] [RFC PATCH v4 13/20] sev: add LAUNCH_UPDATE_DATA command, Brijesh Singh, 2017/03/08
[Qemu-devel] [RFC PATCH v4 06/20] core: add new security-policy object,
Brijesh Singh <=
- Re: [Qemu-devel] [RFC PATCH v4 06/20] core: add new security-policy object, Stefan Hajnoczi, 2017/03/23
- Re: [Qemu-devel] [RFC PATCH v4 06/20] core: add new security-policy object, Brijesh Singh, 2017/03/23
- Re: [Qemu-devel] [RFC PATCH v4 06/20] core: add new security-policy object, Stefan Hajnoczi, 2017/03/24
- Re: [Qemu-devel] [RFC PATCH v4 06/20] core: add new security-policy object, Brijesh Singh, 2017/03/24
- Re: [Qemu-devel] [RFC PATCH v4 06/20] core: add new security-policy object, Stefan Hajnoczi, 2017/03/27
- Re: [Qemu-devel] [RFC PATCH v4 06/20] core: add new security-policy object, Brijesh Singh, 2017/03/27
[Qemu-devel] [RFC PATCH v4 11/20] sev: add LAUNCH_START command, Brijesh Singh, 2017/03/08
[Qemu-devel] [RFC PATCH v4 03/20] exec: add guest RAM read and write ops, Brijesh Singh, 2017/03/08