Running XSM-enabled Xen – SELinux

July 03, 2021

Switching from a regular Xen deployment to an XSM-enabled Xen deployment is a matter of rebuilding Xen with XSM support and rebooting the system. Xen comes with an out-of-the-box policy that can be readily applied, which we will use as part of our XSM endeavor.

Rebuilding Xen with XSM support

Let’s rebuild the Xen hypervisor and tools on the system with XSM support:

  • Clean up the previous build by running the make clean command inside the build directory (xen-4.13.1 in our example):
$ make clean
  • Inside the build directory, go to the xen directory:
$ cd xen
  • Launch the Xen configuration using make menuconfig:
$ make menuconfig
  • Navigate to the XSM setting and enable the XSM-related parameters:
Common Features --->
 [*] Xen Security Modules support
 [*] FLux Advanced Security Kernel support
 [*] Compile Xen with a built-in FLAS security 
 [*] SILO support
 Default XSM implementation (FLux Advanced 
 Security Kernel)
  • Go back to the main build directory (xen-4.13.1 in our example):
$ cd ..
  • Rebuild the Xen hypervisor and tools:
$ ./configure
$ make world
  • Install the updated Xen build on the system:
# make install

This will not only update the tools but will also provide an updated Xen kernel and an XSM policy inside /boot (named xenpolicy-4.13.1).

  • Reconfigure the boot loader with the new Xen build, ensuring that the XSM policy is also loaded with it:
# grub2-mkconfig -o /boot/grub2/grub.cfg
  • Reboot the system:
# reboot
  • Once rebooted, we can verify that the XSM policy is loaded and used by querying Xen for the labels associated with the running guests:
# xl list -Z
Name ID ... Security Label
Domain-0 0 ... system_u:system_r:dom0_t
alpina-a1 1 ... system_u:system_r:domU_t

If the xl list command, given the -Z argument, lists the security labels, then Xen is running with an XSM policy active. Let’s see where these labels are used.

Using XSM labels

When Xen boots with XSM support and has its default policy active, the following types can be used by guests:

  • The dom0_t type is reserved for the privileged guest.
  • The domU_t type is the default type to use for unprivileged guests.
  • The isolated_domU_t type is the type to assign to unprivileged guests that should not be able to interact with other unprivileged guests, only with the privileged dom0 one.
  • The prot_domU_t type is meant for guests that will be prevented from starting if the XSM policy boolean prot_doms_locked is set.
  • The nomigrate_t type is applied to guests that are not allowed to be migrated from one Xen host to another. Internally, this prevents the dom0 guest from accessing the guest’s memory once booted.

There are a few other types also available inside the XSM policy that are not meant for regular guests themselves:

  • The dm_dom_t type is assigned to the device model guest. This is a special, privileged guest that represents the hardware virtualized for an HVM-type guest, without jeopardizing dom0.
  • The xenstore_t type is assigned to the xenstore stub guest. This is a special, privileged guest that provides support for unprivileged guests to access their virtualized resources, without jeopardizing dom0.
  • The nic_dev_t type is assigned to hardware devices that can be used in passthrough mode (meaning domU guests can directly interact with these hardware devices rather than going through the privileged guests).

These stub guests (stub domains or stubdoms as they are called in Xen) are a way for Xen to further increase its security posture, as privileged operations that cannot be prevented are more isolated from dom0. If at any point a security vulnerability can be exploited in these privileged services, they do not necessarily affect dom0 and, with a proper XSM policy, can even be mitigated fully.

Assigning one of these labels to a guest is a matter of editing the guest’s configuration file inside /etc/xen and adding in the seclabel configuration parameter:

seclabel = 'system_u:system_r:isolated_domU_t'

Once configured and rebooted (using xl create), the new label will be visible when querying the running guests:

# xl list -Z
Name ID ... Security Label
Domain-0 0 ... system_u:system_r:dom0_t
alpina-a1 1 ... system_u:system_r:isolated_domU_t

Applying the right label to the guest is the most common use case (as it effectively handles the access control and protection measures we seek from the XSM implementation), but other operations are supported as well.

Manipulating XSM

As with SELinux, several activities can be executed to further manipulate the XSM subsystem or the active policy.

Defining the state, ranging from disabled to enforcing

When Xen boots, we can add a kernel parameter called flask, which can be set to one of the following values:

  • With flask=enforcing, we ensure that XSM is active, enforcing the policy between its guests and resources, and that the enforcement is immediate (no delayed activation).
  • With flask=permissive, XSM will load the policy, but XSM will not enforce the rules set in the policy. This is obviously meant for development purposes and behaves similarly to SELinux’s permissive mode.
  • With flask=late, XSM will not enforce any access controls until a policy is loaded, after which the policy is enforced. This allows administrators to boot with XSM active, but only to load and apply a policy when the administrator deems it ready.
  • With flask=disabled, XSM will not enforce any access controls nor load the policy.

This parameter can be set either directly when booting (from the boot loader) or through the boot loader configuration on the system. For instance, with GRUB2, we can edit /etc/default/grub and add or modify the following parameter:


Don’t forget to regenerate the GRUB2 configuration file:

# grub2-mkconfig -o /boot/grub2/grub.cfg

As with SELinux, we can also manipulate the state of XSM through the command line. With xl getenforce, we can query the current state:

# xl getenforce

The xl setenforce command can be used to switch to another state:

# xl setenforce permissive

These commands have nothing to do with the SELinux configuration within dom0: switching Xen from permissive mode to enforcing or vice versa is specific to Xen and has no impact on the SELinux settings inside dom0.

Querying XSM logs

Like SELinux, XSM also uses AVC logging to provide feedback to the administrator about the decisions it has taken. With xl dmesg, we can query this log information (alongside the other Xen output logging):

# xl dmesg
(XEN) avc: granted { setenforce } for domid=0 scontext=system_u:system_r:dom0_t tcontext=system_u:system_r:security_t tclass=security

Not all granted operations will be logged, but denied operations will always result in an AVC entry. The AVC entries themselves are fully formatted like SELinux AVC entries, allowing administrators to use SELinux tools such as audit2allow to generate XSM policies.

Using XSM booleans

The default policy enabled by Xen has two booleans that can be toggled:

  • The guest_writeconsole boolean, which defaults to 1 (on), allows guests to access and write to the Xen console.
  • The prot_doms_locked boolean, which defaults to 0 (off), will disallow prot_domU_t guests from launching if enabled.

While no subcommand is available for the xl command to query and set XSM booleans, two other commands are installed on the system to accomplish this – flask-get-bool and flask-set-bool:

  • With flask-get-bool, we can query the current state of a boolean, or list all booleans with their current value:
# flask-get-bool -a
guest_writeconsole: 1
prot_doms_locked: 0
  • The flask-set-bool command is used to toggle booleans:
# flask-set-bool prot_doms_locked 1

This is very similar to SELinux’s getsebool and setsebool commands.

Querying the XSM policy

The XSM policy file (xenpolicy-4.13.1) is quite similar to an SELinux policy file. As a result, we can use the SELinux tools to query this file and learn more about the policy:

  • With seinfo, we can query statistics about the policy, view which classes are supported, the constraints that are enabled within, and more. The only query that fails is listing the types supported within the policy:
$ seinfo --all ./xenpolicy-4.13.1
  • With sesearch, we can query the XSM policy rules themselves, for instance, to list all allow rules:
$ sesearch -A ./xenpolicy-4.13.1

Labeling hardware resources

With the flask-label-pci command, administrators can label specified PCI devices with a given type. This approach allows administrators to mark certain devices for passthrough access by unprivileged guests.

For instance, to label the PCI device with address 3:2:0 with the nic_dev_t type, use the following

# flask-label-pci 0000:03:02.0 system_u:object_r:nic_dev_t

As you might guess from the name, this type is initially defined for passthrough access to network devices but can be used for other PCI hardware as well.

Related Articles

How to add swap space on Ubuntu 21.04 Operating System

How to add swap space on Ubuntu 21.04 Operating System

The swap space is a unique space on the disk that is used by the system when Physical RAM is full. When a Linux machine runout the RAM it use swap space to move inactive pages from RAM. Swap space can be created into Linux system in two ways, one we can create a...

read more

Lorem ipsum dolor sit amet consectetur


Submit a Comment

Your email address will not be published. Required fields are marked *

four × 2 =