Add support for security relabeling

virt-install already supports relabeling, but virt-manager doesn't and
in some cases, this can cause problems, for example when switching to
dynamic labeling with the relabeling turned off.  I took the approach
of allowing the user to choose, with safe fallbacks to defaults.

Deals also with this:

https://bugzilla.redhat.com/show_bug.cgi?id=907390
This commit is contained in:
Martin Kletzander 2013-02-05 12:28:06 +01:00 committed by Cole Robinson
parent 46c8ee58dc
commit b6f0ba364f
3 changed files with 54 additions and 12 deletions

View File

@ -1,5 +1,5 @@
# #
# Copyright (C) 2006-2008 Red Hat, Inc. # Copyright (C) 2006-2008, 2013 Red Hat, Inc.
# Copyright (C) 2006 Daniel P. Berrange <berrange@redhat.com> # Copyright (C) 2006 Daniel P. Berrange <berrange@redhat.com>
# #
# This program is free software; you can redistribute it and/or modify # This program is free software; you can redistribute it and/or modify
@ -407,6 +407,7 @@ class vmmDetails(vmmGObjectUI):
"on_overview_clock_changed": (self.enable_apply, EDIT_CLOCK), "on_overview_clock_changed": (self.enable_apply, EDIT_CLOCK),
"on_machine_type_changed": (self.enable_apply, EDIT_MACHTYPE), "on_machine_type_changed": (self.enable_apply, EDIT_MACHTYPE),
"on_security_label_changed": (self.enable_apply, EDIT_SECURITY), "on_security_label_changed": (self.enable_apply, EDIT_SECURITY),
"on_security_relabel_changed": (self.enable_apply, EDIT_SECURITY),
"on_security_type_changed": self.security_type_changed, "on_security_type_changed": self.security_type_changed,
"on_config_vcpus_changed": self.config_vcpus_changed, "on_config_vcpus_changed": self.config_vcpus_changed,
@ -786,7 +787,7 @@ class vmmDetails(vmmGObjectUI):
# Security info tooltips # Security info tooltips
util.tooltip_wrapper(self.widget("security-static-info"), util.tooltip_wrapper(self.widget("security-static-info"),
_("Static SELinux security type tells libvirt to always start the guest process with the specified label. The administrator is responsible for making sure the images are labeled correctly on disk.")) _("Static SELinux security type tells libvirt to always start the guest process with the specified label. Unless 'relabel' is set, the administrator is responsible for making sure the images are labeled correctly on disk."))
util.tooltip_wrapper(self.widget("security-dynamic-info"), util.tooltip_wrapper(self.widget("security-dynamic-info"),
_("The dynamic SELinux security type tells libvirt to automatically pick a unique label for the guest process and guest image, ensuring total isolation of the guest. (Default)")) _("The dynamic SELinux security type tells libvirt to automatically pick a unique label for the guest process and guest image, ensuring total isolation of the guest. (Default)"))
@ -1740,6 +1741,7 @@ class vmmDetails(vmmGObjectUI):
def security_type_changed(self, button): def security_type_changed(self, button):
self.enable_apply(EDIT_SECURITY) self.enable_apply(EDIT_SECURITY)
self.widget("security-label").set_sensitive(not button.get_active()) self.widget("security-label").set_sensitive(not button.get_active())
self.widget("security-relabel").set_sensitive(not button.get_active())
# Memory # Memory
def config_get_maxmem(self): def config_get_maxmem(self):
@ -2021,13 +2023,15 @@ class vmmDetails(vmmGObjectUI):
semodel = None semodel = None
setype = "static" setype = "static"
selabel = self.get_text("security-label") selabel = self.get_text("security-label")
relabel = self.widget("security-relabel").get_active()
if self.widget("security-dynamic").get_active(): if self.widget("security-dynamic").get_active():
setype = "dynamic" setype = "dynamic"
relabel = True
if self.widget("security-type-box").get_property("sensitive"): if self.widget("security-type-box").get_property("sensitive"):
semodel = self.get_text("security-model") semodel = self.get_text("security-model")
add_define(self.vm.define_seclabel, semodel, setype, selabel) add_define(self.vm.define_seclabel, semodel, setype, selabel, relabel)
if self.editted(EDIT_DESC): if self.editted(EDIT_DESC):
desc_widget = self.widget("overview-description") desc_widget = self.widget("overview-description")
@ -2603,7 +2607,7 @@ class vmmDetails(vmmGObjectUI):
self.set_combo_label("machine-type", machtype) self.set_combo_label("machine-type", machtype)
# Security details # Security details
semodel, ignore, vmlabel = self.vm.get_seclabel() semodel, sectype, vmlabel, relabel = self.vm.get_seclabel()
caps = self.vm.conn.get_capabilities() caps = self.vm.conn.get_capabilities()
if caps.host.secmodel and caps.host.secmodel.model: if caps.host.secmodel and caps.host.secmodel.model:
@ -2617,11 +2621,19 @@ class vmmDetails(vmmGObjectUI):
else: else:
self.widget("security-type-box").set_sensitive(bool(semodel)) self.widget("security-type-box").set_sensitive(bool(semodel))
if self.vm.get_seclabel()[1] == "static": if sectype == "static":
self.widget("security-static").set_active(True) self.widget("security-static").set_active(True)
self.widget("security-relabel").set_sensitive(True)
# As "no" is default for relabel with 'static' label and
# 'dynamic' must have relabel='yes', this will work properly
# for both False (relabel='no') and None (relabel not
# specified)
self.widget("security-relabel").set_active(relabel)
else: else:
self.widget("security-dynamic").set_active(True) self.widget("security-dynamic").set_active(True)
# Dynamic label type must use resource labeling
self.widget("security-relabel").set_active(True)
self.widget("security-relabel").set_sensitive(False)
self.widget("security-label").set_text(vmlabel) self.widget("security-label").set_text(vmlabel)
def refresh_stats_page(self): def refresh_stats_page(self):

View File

@ -491,13 +491,19 @@ class vmmDomain(vmmLibvirtObject):
# Security define methods # Security define methods
def define_seclabel(self, model, t, label): def define_seclabel(self, model, t, label, relabel):
def change(guest): def change(guest):
seclabel = guest.seclabel seclabel = guest.seclabel
seclabel.model = model or None seclabel.model = model or None
if not model: if not model:
return return
if relabel is not None:
if relabel:
seclabel.relabel = "yes"
else:
seclabel.relabel = "no"
seclabel.type = t seclabel.type = t
if label: if label:
seclabel.label = label seclabel.label = label
@ -937,11 +943,19 @@ class vmmDomain(vmmLibvirtObject):
return (kernel, initrd, args) return (kernel, initrd, args)
def get_seclabel(self): def get_seclabel(self):
model = self._get_guest().seclabel.model seclabel = self._get_guest().seclabel
t = self._get_guest().seclabel.type or "dynamic" model = seclabel.model
label = self._get_guest().seclabel.label or "" t = seclabel.type or "dynamic"
label = seclabel.label or ""
return [model, t, label] relabel = getattr(seclabel, "relabel", None)
if relabel is not None:
if relabel == "yes":
relabel = True
else:
relabel = False
return [model, t, label, relabel]
# XML Device listing # XML Device listing

View File

@ -1746,6 +1746,22 @@
<property name="position">1</property> <property name="position">1</property>
</packing> </packing>
</child> </child>
<child>
<object class="GtkCheckButton" id="security-relabel">
<property name="label" translatable="yes">relabel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="draw_indicator">True</property>
<signal name="toggled" handler="on_security_relabel_changed" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object> </object>
<packing> <packing>
<property name="right_attach">2</property> <property name="right_attach">2</property>
@ -2007,7 +2023,7 @@ I/O:</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="xalign">0</property> <property name="xalign">0</property>
<property name="label">30 MB of <property name="label">30 MB of
128 MB</property> 128 MB</property>
</object> </object>
<packing> <packing>