Certain virtualization environments require the extra security provided by XSM and FLASK (https://wiki.xenproject.org/wiki/Xen_Security_Modules_:_XSM-FLASK). XenServer 7 benefits from its upgrade of the control domain to CentOS 7, which includes support for enabling XSM and FLASK. But what about legacy XenServer 6.5 installations that also require the added security? XSM and FLASK may be enabled on XenServer 6.5 as well, but it requires a bit more work.
Note that XSM is not currently a user-visible feature in XenServer, or a supported technology.
This article describes how to enable XSM and FLASK in XenServer 6.5 SP1. It makes the assumption that the reader is familiar with accessing, building, and deploying XenServer's Xen RPMs from source. While this article pertains to resources from SP1 source RPMs (XS65ESP1-src-pkgs.tar.bz2 included with SP1, http://support.citrix.com/article/CTX142355), a similar approach can be followed for other XenServer 6.5 hotfixes.
2 Patching Xen and xen.spec
XenServer issues some hypercalls not handled by Xen's XSM hooks. The following patch shows one possible way to handle these operations and commands, which is to always permit them.
diff --git a/xs6.5sp1/xen/xen-4.4.1/xen/xsm/flask/hooks.c b/xs6.5sp1/xen/xen-4.4.1/xen/xsm/flask/hooks.c index 0cf7daf..a41fcc4 100644 --- a/xs6.5sp1/xen/xen-4.4.1/xen/xsm/flask/hooks.c +++ b/xs6.5sp1/xen/xen-4.4.1/xen/xsm/flask/hooks.c @@ -727,6 +727,12 @@ static int flask_domctl(struct domain *d, int cmd) case XEN_DOMCTL_cacheflush: return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__CACHEFLUSH); + case XEN_DOMCTL_get_runstate_info: + return 0; + + case XEN_DOMCTL_setcorespersocket: + return 0; + default: printk("flask_domctl: Unknown op %dn", cmd); return -EPERM; @@ -782,6 +788,9 @@ static int flask_sysctl(int cmd) case XEN_SYSCTL_numainfo: return domain_has_xen(current->domain, XEN__PHYSINFO); + case XEN_SYSCTL_consoleringsize: + return 0; + default: printk("flask_sysctl: Unknown op %dn", cmd); return -EPERM; @@ -1299,6 +1308,9 @@ static int flask_platform_op(uint32_t op) case XENPF_get_cpuinfo: return domain_has_xen(current->domain, XEN__GETCPUINFO); + case XENPF_get_cpu_features: + return 0; + default: printk("flask_platform_op: Unknown op %dn", op); return -EPERM;
The only other file that needs patching is Xen's RPM spec file, xen.spec. Modify HV_COMMON_OPTIONS as shown below. Change this line:
% define HV_COMMON_OPTIONS max_phys_cpus=256
% define HV_COMMON_OPTIONS max_phys_cpus=256 XSM_ENABLE=y FLASK_ENABLE=y
3 Compiling and Loading a Policy
To build a security policy, navigate to tools/flask/policy in Xen's source tree. Run make to compile the default security policy. It will have a name like xenpolicy.24, depending on your version of checkpolicy.
Copy xenpolicy.24 over to Dom0's /boot directory. Open /boot/extlinux.conf and modify the default section's append /boot/xen.gz ... line so it has --- /boot/xenpolicy.24 at the end. For example:
append /boot/xen.gz dom0_mem=752M,max:752M [.. snip ..] splash --- /boot/initrd-3.10-xen.img --- /boot/xenpolicy.24
After making this change, reboot.
While booting (or afterwards, via xl dmesg), you should see messages indicating XSM and FLASK initialized, read the security policy, and started in permissive mode. For example:
(XEN) XSM Framework v1.0.0 initialized (XEN) Policy len 0x1320, start at ffff830117ffe000. (XEN) Flask: Initializing. (XEN) AVC INITIALIZED (XEN) Flask: Starting in permissive mode.
4 Exercises for the Reader
- Create a more sophisticated implementation for handling XenServer hypercalls in xen/xsm/flask/hooks.c.
- Write (and load) a custom policy.
- Boot with flask_enforcing=1 set, and study any violations that occur (see xl dmesg output).