@@ -42,6 +42,7 @@
#include "exec/memory.h"
#include "exec/ioport.h"
#include "sysemu/dma.h"
+#include "sysemu/security-policy.h"
#include "exec/address-spaces.h"
#include "sysemu/xen-mapcache.h"
#include "trace.h"
@@ -2764,6 +2765,12 @@ static inline void cpu_physical_memory_rw_debug_internal(AddressSpace *as,
hwaddr addr1;
MemoryRegion *mr;
+ if (attrs.debug &&
+ !security_policy_debug_allowed(current_machine->security_policy)) {
+ fprintf(stderr, "WARNING: debug is disabled\n");
+ return;
+ }
+
rcu_read_lock();
while (len > 0) {
l = len;
@@ -18,5 +18,6 @@ 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
@@ -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",
@@ -462,6 +479,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)
new file mode 100644
@@ -0,0 +1,166 @@
+/*
+ * QEMU security policy support
+ *
+ * Copyright (c) 2016 Advanced Micro Devices
+ *
+ * Author:
+ * Brijesh Singh <brijesh.singh@amd.com>
+ *
+ * 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 "trace.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);
@@ -150,6 +150,7 @@ struct MachineState {
/*< public >*/
char *accel;
+ char *security_policy;
bool kernel_irqchip_allowed;
bool kernel_irqchip_required;
bool kernel_irqchip_split;
new file mode 100644
@@ -0,0 +1,75 @@
+/*
+ * QEMU security policy support
+ *
+ * Copyright (c) 2016 Advanced Micro Devices
+ *
+ * Author:
+ * Brijesh Singh <brijesh.singh@amd.com>
+ *
+ * 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 */
@@ -4027,6 +4027,27 @@ contents of @code{iv.b64} to the second secret
@end table
+@item -object security-policy,id=@var{id}[,debug=@var{bool}][,memory-encryption=@var{string}]
+
+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
+@example
+ # $QEMU \
+ -object security-policy,id=secure0,debug=off \
+ -machine ...,security-policy=secure0
+@end 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
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 from qemu monitor # $QEMU \ -object security-policy,debug=false,id=mypolicy \ -machine ...,security-policy=mypolicy 2) memory-encryption: if guest supports memory encryption then property should be set to memory encryption object id. # $QEMU \ -object sev-guest,id=sev0 \ -object security-policy,id=memory-encryption=sev0,id=mypolicy \ -machine ...,security-policy=mypolicy Signed-off-by: Brijesh Singh <brijesh.singh@amd.com> --- exec.c | 7 ++ hw/core/Makefile.objs | 1 hw/core/machine.c | 22 +++++ hw/core/security-policy.c | 166 ++++++++++++++++++++++++++++++++++++++ include/hw/boards.h | 1 include/sysemu/security-policy.h | 75 +++++++++++++++++ qemu-options.hx | 21 +++++ 7 files changed, 293 insertions(+) create mode 100644 hw/core/security-policy.c create mode 100644 include/sysemu/security-policy.h