Skip to content

Commit

Permalink
flask/policy: split into modules
Browse files Browse the repository at this point in the history
This makes it easier to enable or disable parts of the XSM policy.

Signed-off-by: Daniel De Graaf <[email protected]>
Reviewed-by: Konrad Rzeszutek Wilk <[email protected]>
Reviewed-by: Doug Goldstein <[email protected]>
  • Loading branch information
dgdegraaf authored and andyhhp committed Jun 21, 2016
1 parent 57a5746 commit 31689dc
Show file tree
Hide file tree
Showing 13 changed files with 302 additions and 302 deletions.
22 changes: 7 additions & 15 deletions tools/flask/policy/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ POLICY_VER_LIST_HV = 24 30

# policy source layout
POLDIR := policy
MODDIR := $(POLDIR)/modules
MODDIR := modules

# Classes and access vectors defined in the hypervisor. Changes to these require
# a recompile of both the hypervisor and security policy.
Expand All @@ -60,7 +60,7 @@ DEV_OCONS := $(POLDIR)/device_contexts

# config file paths
GLOBALTUN := $(POLDIR)/global_tunables
MOD_CONF := $(POLDIR)/modules.conf
MOD_CONF := $(MODDIR)/modules.conf

# checkpolicy can use the #line directives provided by -s for error reporting:
M4PARAM := -D self_contained_policy -s
Expand All @@ -84,22 +84,14 @@ endif
M4PARAM += -D mls_num_sens=$(MLS_SENS) -D mls_num_cats=$(MLS_CATS)


# Find modules
ALL_LAYERS := $(filter-out $(MODDIR)/CVS,$(shell find $(wildcard $(MODDIR)/*) -maxdepth 0 -type d))

# sort here since it removes duplicates, which can happen
# when a generated file is already generated
DETECTED_MODS := $(sort $(foreach dir,$(ALL_LAYERS),$(wildcard $(dir)/*.te)))

# modules.conf setting for policy configuration
MODENABLED := on

# extract settings from modules.conf
ENABLED_MODS := $(foreach mod,$(shell awk '/^[ \t]*[a-z]/{ if ($$3 == "$(MODENABLED)") print $$1 }' $(MOD_CONF) 2> /dev/null),$(subst ./,,$(shell find -iname $(mod).te)))

ALL_MODULES := $(filter $(ENABLED_MODS),$(DETECTED_MODS))
ENABLED_LIST := $(shell awk '/^[ \t]*[a-z]/{ if ($$3 == "$(MODENABLED)") print $$1 }' $(MOD_CONF) 2> /dev/null)

ALL_INTERFACES := $(ALL_MODULES:.te=.if)
ALL_MODULES := $(foreach mod,$(ENABLED_LIST),$(MODDIR)/$(mod).te)
ALL_INTERFACES := $(wildcard $(ALL_MODULES:.te=.if))

# The order of these files is important
POLICY_SECTIONS := $(SECCLASS) $(ISID_DECLS) $(AVS)
Expand All @@ -118,8 +110,8 @@ install: $(POLICY_FILENAME)
$(POLICY_FILENAME): policy.conf
$(CHECKPOLICY) $(CHECKPOLICY_PARAM) $^ -o $@

policy.conf: $(POLICY_SECTIONS)
$(M4) $(M4PARAM) $^ > $@
policy.conf: $(POLICY_SECTIONS) $(MOD_CONF)
$(M4) $(M4PARAM) $(POLICY_SECTIONS) > $@

clean:
$(RM) tmp policy.conf $(POLICY_FILENAME)
Expand Down
74 changes: 74 additions & 0 deletions tools/flask/policy/modules/dom0.te
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
################################################################################
#
# Allow dom0 access to all sysctls, devices, and the security server.
#
# While this could be written more briefly using wildcards, the permissions are
# listed out to make removing specific permissions simpler.
#
################################################################################
allow dom0_t xen_t:xen {
settime tbufcontrol readconsole clearconsole perfcontrol mtrr_add
mtrr_del mtrr_read microcode physinfo quirk writeconsole readapic
writeapic privprofile nonprivprofile kexec firmware sleep frequency
getidle debug getcpuinfo heap pm_op mca_op lockprof cpupool_op tmem_op
tmem_control getscheduler setscheduler
};
allow dom0_t xen_t:xen2 {
resource_op psr_cmt_op psr_cat_op pmu_ctrl get_symbol
get_cpu_levelling_caps get_cpu_featureset livepatch_op
};

# Allow dom0 to use all XENVER_ subops that have checks.
# Note that dom0 is part of domain_type so this has duplicates.
allow dom0_t xen_t:version {
xen_extraversion xen_compile_info xen_capabilities
xen_changeset xen_pagesize xen_guest_handle xen_commandline
xen_build_id
};

allow dom0_t xen_t:mmu memorymap;

# Allow dom0 to use these domctls on itself. For domctls acting on other
# domains, see the definitions of create_domain and manage_domain.
allow dom0_t dom0_t:domain {
setvcpucontext max_vcpus setaffinity getaffinity getscheduler
getdomaininfo getvcpuinfo getvcpucontext setdomainmaxmem setdomainhandle
setdebugging hypercall settime setaddrsize getaddrsize trigger
getextvcpucontext setextvcpucontext getvcpuextstate setvcpuextstate
getpodtarget setpodtarget set_misc_info set_virq_handler
};
allow dom0_t dom0_t:domain2 {
set_cpuid gettsc settsc setscheduler set_max_evtchn set_vnumainfo
get_vnumainfo psr_cmt_op psr_cat_op
};
allow dom0_t dom0_t:resource { add remove };

# These permissions allow using the FLASK security server to compute access
# checks locally, which could be used by a domain or service (such as xenstore)
# that does not have its own security server to make access decisions based on
# Xen's security policy.
allow dom0_t security_t:security {
compute_av compute_create compute_member compute_relabel compute_user
};

# Allow string/SID conversions (for "xl list -Z" and similar)
allow dom0_t security_t:security check_context;

# Allow flask-label-pci to add and change labels
allow dom0_t security_t:security { add_ocontext del_ocontext };

# Allow performance parameters of the security server to be tweaked
allow dom0_t security_t:security setsecparam;

# Allow changing the security policy
allow dom0_t security_t:security { load_policy setenforce setbool };

# Audit policy change events even when they are allowed
auditallow dom0_t security_t:security { load_policy setenforce setbool };

admin_device(dom0_t, device_t)
admin_device(dom0_t, irq_t)
admin_device(dom0_t, ioport_t)
admin_device(dom0_t, iomem_t)

domain_comms(dom0_t, dom0_t)
25 changes: 25 additions & 0 deletions tools/flask/policy/modules/domU.te
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
###############################################################################
#
# Domain creation
#
###############################################################################

declare_domain(domU_t)
domain_self_comms(domU_t)
create_domain(dom0_t, domU_t)
manage_domain(dom0_t, domU_t)
domain_comms(dom0_t, domU_t)
domain_comms(domU_t, domU_t)
migrate_domain_out(dom0_t, domU_t)
domain_self_comms(domU_t)

# Device model for domU_t. You can define distinct types for device models for
# domains of other types, or add more make_device_model lines for this type.
declare_domain(dm_dom_t)
create_domain(dom0_t, dm_dom_t)
manage_domain(dom0_t, dm_dom_t)
domain_comms(dom0_t, dm_dom_t)
make_device_model(dom0_t, dm_dom_t, domU_t)

# This is required for PCI (or other device) passthrough
delegate_devices(dom0_t, domU_t)
31 changes: 31 additions & 0 deletions tools/flask/policy/modules/guest_features.te
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Allow all domains to use (unprivileged parts of) the tmem hypercall
allow domain_type xen_t:xen tmem_op;

# Allow all domains to use PMU (but not to change its settings --- that's what
# pmu_ctrl is for)
allow domain_type xen_t:xen2 pmu_use;

# Allow guest console output to the serial console. This is used by PV Linux
# and stub domains for early boot output, so don't audit even when we deny it.
# Without XSM, this is enabled only if the Xen was compiled in debug mode.
gen_bool(guest_writeconsole, true)
if (guest_writeconsole) {
allow domain_type xen_t : xen writeconsole;
} else {
dontaudit domain_type xen_t : xen writeconsole;
}

# For normal guests, allow all queries except XENVER_commandline.
allow domain_type xen_t:version {
xen_extraversion xen_compile_info xen_capabilities
xen_changeset xen_pagesize xen_guest_handle
};

# Version queries don't need auditing when denied. They can be
# encountered in normal operation by xl or by reading sysfs files in
# Linux, so without this they will show up in the logs. Since these
# operations return valid responses (like "denied"), hiding the denials
# should not break anything.
dontaudit domain_type xen_t:version {
xen_commandline xen_build_id
};
7 changes: 7 additions & 0 deletions tools/flask/policy/modules/isolated_domU.te
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
declare_domain(isolated_domU_t)
create_domain(dom0_t, isolated_domU_t)
manage_domain(dom0_t, isolated_domU_t)
domain_comms(dom0_t, isolated_domU_t)
migrate_domain_out(dom0_t, isolated_domU_t)
domain_self_comms(isolated_domU_t)

34 changes: 34 additions & 0 deletions tools/flask/policy/modules/modules.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#
# This file contains a listing of available modules.
#
# To prevent a module from being used in policy creation, set the module name
# to "off"; otherwise, set the module name on "on".
#
# The order the modules appear in this file is the order they will be parsed;
# this can be important if you plan to use types defined in one file in another.
#

# Basic types and classes for the Xen hypervisor. This module is required.
xen = on

# Permissions for domain 0. Most of these are required to boot.
dom0 = on

# Allow all domains the ability to use access-controlled features and hypercalls
# that are not restricted when XSM is disabled.
guest_features = on

# The default domain type (domU_t) and its device model (dm_dom_t). The domain
# is created and managed by dom0_t, and has no special restrictions.
#
# This is required if you want to be able to create domains without specifying
# their XSM label in the configuration.
domU = on

# Example types with restrictions
isolated_domU = on
prot_domU = on
nomigrate = on

# Example device policy. Also see policy/device_contexts.
nic_dev = on
14 changes: 14 additions & 0 deletions tools/flask/policy/modules/nic_dev.te
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
###############################################################################
#
# Device delegation
#
# This requires that the device be labeled with a type defined here. You can
# use flask-label-pci to dynamically label devices on each boot or define the
# labels statically in tools/flask/policy/policy/device_contexts
#
###############################################################################

type nic_dev_t, resource_type;

admin_device(dom0_t, nic_dev_t)
use_device(domU_t, nic_dev_t)
8 changes: 8 additions & 0 deletions tools/flask/policy/modules/nomigrate.te
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Domains of type nomigrate_t must be built via the nomigrate_t_building label;
# once built, dom0 cannot read their memory.
declare_domain(nomigrate_t)
declare_build_label(nomigrate_t)
create_domain_build_label(dom0_t, nomigrate_t)
manage_domain(dom0_t, nomigrate_t)
domain_comms(dom0_t, nomigrate_t)
domain_self_comms(nomigrate_t)
13 changes: 13 additions & 0 deletions tools/flask/policy/modules/prot_domU.te
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# This is an alternative to nomigrate_t: a policy boolean controls the ability
# to create or migrate a domain of type prot_domU_t. If disabled, dom0 cannot
# map memory belonging to those domains.
gen_bool(prot_doms_locked, false)
declare_domain(prot_domU_t)
if (!prot_doms_locked) {
create_domain(dom0_t, prot_domU_t)
migrate_domain_out(dom0_t, prot_domU_t)
}
domain_comms(dom0_t, prot_domU_t)
domain_comms(domU_t, prot_domU_t)
domain_comms(prot_domU_t, prot_domU_t)
domain_self_comms(prot_domU_t)
File renamed without changes.
89 changes: 89 additions & 0 deletions tools/flask/policy/modules/xen.te
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
################################################################################
#
# Attributes for types
#
# An attribute may be used in a rule as shorthand for all types with that
# attribute.
#
################################################################################
attribute xen_type;
attribute domain_type;
attribute domain_self_type;
attribute domain_target_type;
attribute resource_type;
attribute event_type;
attribute mls_priv;

################################################################################
#
# Types for the initial SIDs
#
# These types are used internally for objects created during Xen startup or for
# devices that have not yet been labeled
#
################################################################################

# The hypervisor itself
type xen_t, xen_type, mls_priv;

# Domain 0
declare_singleton_domain(dom0_t, mls_priv);

# I/O memory (DOMID_IO pseudo-domain)
type domio_t, xen_type;

# Xen heap (DOMID_XEN pseudo-domain)
type domxen_t, xen_type;

# Unlabeled objects
type unlabeled_t, xen_type;

# The XSM/FLASK security server
type security_t, xen_type;

# Unlabeled device resources
# Note: don't allow access to these types directly; see below for how to label
# devices and use that label for allow rules
type irq_t, resource_type;
type ioport_t, resource_type;
type iomem_t, resource_type;
type device_t, resource_type;

################################################################################
#
# Policy constraints
#
# Neverallow rules will cause the policy build to fail if an allow rule exists
# that violates the expression. This is used to ensure proper labeling of
# objects.
#
################################################################################

# Domains must be declared using domain_type
neverallow * ~domain_type:domain { create transition };

# Resources must be declared using resource_type
neverallow * ~resource_type:resource use;

# Events must use event_type (see create_channel for a template)
neverallow ~event_type *:event bind;
neverallow * ~event_type:event { create send status };

################################################################################
#
# Roles
#
################################################################################

# The object role (object_r) is used for devices, resources, and event channels;
# it does not need to be defined here and should not be used for domains.

# The system role is used for utility domains and pseudo-domains
role system_r;
role system_r types { xen_type domain_type };
# If you want to prevent domUs from being placed in system_r:
##role system_r types { xen_type dom0_t };

# The vm role is used for customer virtual machines
role vm_r;
role vm_r types { domain_type -dom0_t };
15 changes: 0 additions & 15 deletions tools/flask/policy/policy/modules.conf

This file was deleted.

Loading

0 comments on commit 31689dc

Please sign in to comment.