These notes are compiled from xen-devel questions and postings that have occurred since the inclusion of XSM. These notes are not intended to be definitive documentation but should address many common problems that arise when experimenting with XSM:FLASK. Xen XSM:FLASK configuration --------------------------- 1) cd xen-unstable.hg 2) edit Config.mk in the toplevel xen directory as follows: XSM_ENABLE ?= y FLASK_ENABLE ?= y ACM_SECURITY ?= n NB: Only one security module can be selected at a time. If no module is selected, then the default DUMMY module will be enforced. The DUMMY module only exercises the security framework and does not enforce any security policies. Changing the security module selection will require recompiling xen. These settings will also configure the corresponding toolchain support. 3) make xen 4) make tools Xen XSM:FLASK policy -------------------- These instructions will enable the configuration and build of the sample policy. The sample policy provides the MINIMUM policy necessary to boot a paravirtualized dom0 and create a pv or hvm domU. Many of the default capabilities and usages supported by dom0/domU are disallowed by the sample policy. Further, the policy is comprised of a limited number of types and must be adjusted to meet the specific security goals of the installation. Modification of the policy is straightforward and is covered in a later section. NB: The policy is not automatically built as part of the tool support because of an external dependancy on the checkpolicy compiler. The FLASK policy uses the same syntax and structure as SELinux and compiling the policy relies on the SELinux policy toolchain. This toolchain is available under many distributions as well as the following URL, http://userspace.selinuxproject.org/trac/wiki/Releases You will need at least libsepol and checkpolicy in order to compile a policy. 1) cd xen-unstable.hg/tools/flask/policy 2) make policy 3) make install 4) edit /etc/grub.conf, add a module line to the xen entry, module /xenpolicy.24 NB: The .24 suffix reflects the policy format version and may differ for your system depending on the version of checkpolicy you used to build the policy. At the time of this writing, policy version 24 is the highest version supported by the latest checkpolicy release and by the Xen Flask module. You can force the policy build to a specific policy version by uncommenting the OUTPUT_POLICY= line in the policy Makefile and setting the value as desired (to any version supported by the Xen Flask module, presently in the range 15-24). Make sure that your module line above matches the actual /xenpolicy.NN file that was created in /boot by the make install. 5) reboot, and select the updated xen entry NB: The module entry can be inserted on any line after the xen kernel line. Typical configurations use the last module entry or the module entry that immediately follows the xen kernel entry. If you want to use the MLS policy, then set TYPE=xen-mls in the policy Makefile before building the policy. Note that the MLS constraints in policy/mls are incomplete and are only a sample. Xen configuration of xend ------------------------- 1) cd /etc/xen 2) edit xend-config.sxp 3) uncomment the line containing the key:value pair entry, #(xsm_module_name dummy) 4) change the value entry to 'flask' (xsm_module_name flask) 5) restart xend Creating policy controlled domains ---------------------------------- 2) Edit the domain config file and add the following entry for a pv guest, access_control = ["policy=,label=system_u:system_r:domU_t"] or add the following entry for a hvm guest: access_control = ["policy=,label=system_u:system_r:domHU_t"] NB: The 'policy' field is not used by XSM:FLASK. The 'label' must exist in the loaded policy. 'system_u:system_r:domU_t' is one of the existing labels from the sample policy and shown for example purposes. If you enabled the MLS policy, then append a MLS level (e.g. s0:c0) to the labels, e.g.: access_control = ["policy=,label=system_u:system_r:domU_t:s0:c0"] 2) Create the domain using the 'xm create' command. 3) Use the 'xm list --label' command to list the running domains and their labels. Updating the XSM:FLASK policy ----------------------------- It is recommended that the XSM:FLASK policy be tailored to meet the specific security goals of the platform. The policy is tailored by editing the xen.if and xen.te files in the 'policy' subdirectory. 1) cd xen-unstable.hg/tools/flask/policy 2) edit policy/modules/xen/xen.* - make changes to support platform security goals. 3) make policy 4) make install 5) reboot Alternatively, one may reload the policy using the 'flask_loadpolicy' tool installed by the xen tools. 1) flask_loadpolicy policy.24 NB: The sample policy permits policy reloads as well as general manipulation of the Flask security server only from dom0. The policy can be tailored further to restrict policy reloads and other manipulations to boot-time only, by removing the corresponding statements from the policy. Enforcing the XSM:FLASK policy ------------------------------ By default, XSM:FLASK is compiled and installed in permissive mode. This configuration will allow an XSM:FLASK system to start in enforcing mode. 1) edit /etc/grub.conf 2) append the parameter 'flask_enforcing=1' to the xen kernel line. 3) reboot, and select the updated xen entry AVC denials ----------- XSM:Flask will emit avc: denied messages when a permission is denied by the policy, just like SELinux. For example, if you were to use system_u:system_r:domU_t label for a hvm guest (rather than system_u:system_r:domHU_t), you would get a set of denials upon xm create: # xm dmesg | grep avc (XEN) avc: denied { setparam } for domid=0 scontext=system_u:system_r:dom0_t tcontext=system_u:system_r:domU_t tclass=hvm (XEN) avc: denied { getparam } for domid=0 scontext=system_u:system_r:dom0_t tcontext=system_u:system_r:domU_t tclass=hvm (XEN) avc: denied { irqlevel } for domid=0 scontext=system_u:system_r:dom0_t tcontext=system_u:system_r:domU_t tclass=hvm (XEN) avc: denied { pciroute } for domid=0 scontext=system_u:system_r:dom0_t tcontext=system_u:system_r:domU_t tclass=hvm (XEN) avc: denied { setparam } for domid=4 scontext=system_u:system_r:domU_t tcontext=system_u:system_r:domU_t tclass=hvm (XEN) avc: denied { cacheattr } for domid=0 scontext=system_u:system_r:dom0_t tcontext=system_u:system_r:domU_t tclass=hvm (XEN) avc: denied { pcilevel } for domid=0 scontext=system_u:system_r:dom0_t tcontext=system_u:system_r:domU_t tclass=hvm Existing SELinux tools such as audit2allow can be applied to these denials, e.g. xm dmesg | audit2allow The generated allow rules can then be fed back into the policy by adding them to xen.te, although manual review is advised and will often lead to adding parameterized rules to the interfaces in xen.if to address the general case. Device Policy ------------- Flask is capable of labeling devices and enforcing policies associated with them. To enable this functionality the latest version of checkpolicy (>= 2.0.20) and libsepol (>=2.0.39) will be needed in order to compile it. To enable the building of the new policies the following changes will need to be done to tools/flask/policy/Makefile. ######################################## # # Build a binary policy locally # $(POLVER): policy.conf @echo "Compiling $(NAME) $(POLVER)" $(QUIET) $(CHECKPOLICY) $^ -o $@ (Comment out this line) # Uncomment line below to enable policies for devices # $(QUIET) $(CHECKPOLICY) -t Xen $^ -o $@ (Uncomment this line) ######################################## # # Install a binary policy # $(LOADPATH): policy.conf @echo "Compiling and installing $(NAME) $(LOADPATH)" $(QUIET) $(CHECKPOLICY) $^ -o $@ (Comment out this line) # Uncomment line below to enable policies for devices # $(QUIET) $(CHECKPOLICY) -t Xen $^ -o $@ (Uncomment this line) Pirqs, PCI devices, I/O memory and ports can all be labeled. There are commented out lines in xen.te policy for examples on how to label devices. Device Labeling --------------- The "lspci -vvn" command can be used to output all the devices and identifiers associated with them. For example, to label an Intel e1000e ethernet card the lspci output is.. 00:19.0 0200: 8086:10de (rev 02) Subsystem: 1028:0276 Interrupt: pin A routed to IRQ 33 Region 0: Memory at febe0000 (32-bit, non-prefetchable) [size=128K] Region 1: Memory at febd9000 (32-bit, non-prefetchable) [size=4K] Region 2: I/O ports at ecc0 [size=32] Kernel modules: e1000e The labeling can be done with these commands pirqcon 33 system_u:object_r:nicP_t iomemcon 0xfebe0-0xfebff system_u:object_r:nicP_t iomemcon 0xfebd9 system_u:object_r:nicP_t ioportcon 0xecc0-0xecdf system_u:object_r:nicP_t pcidevicecon 0xc800 system_u:object_r:nicP_t Labeling of the PCI device is tricky since there is no output in lspci that makes the information easily available. The easiest way to obtain the information is to look at the avc denial line for the correct hex value. (XEN) avc: denied { add_device } for domid=0 device=0xc800 <--- scontext=system_u:system_r:dom0_t tcontext=system_u:object_r:device_t tclass=resource Additional notes on XSM:FLASK ----------------------------- 1) xen command line parameters a) flask_enforcing The default value for flask_enforcing is '0'. This parameter causes the platform to boot in permissive mode which means that the policy is loaded but not enforced. This mode is often helpful for developing new systems and policies as the policy violations are reported on the xen console and may be viewed in dom0 through 'xm dmesg'. To boot the platform into enforcing mode, which means that the policy is loaded and enforced, append 'flask_enforcing=1' on the grub line. This parameter may also be changed through the flask hyercall. b) flask_enabled The default value for flask_enabled is '1'. This parameter causes the platform to enable the FLASK security module under the XSM framework. The parameter may be enabled/disabled only once per boot. If the parameter is set to '0', only a reboot can re-enable flask. When flask_enabled is '0' the DUMMY module is enforced. This parameter may also be changed through the flask hypercall. But may only be performed once per boot.