Named range file

Updated: April 19, 2023

A named range file allows you to specify ranges to use in a security policy even if the range values are not known until the system boots (for example, address and interrupt ranges for devices). The file gives these ranges names, and the ranges are resolved to their actual values when the policy is pushed to procnto. It can be a fixed file that is part of the IFS or it can be generated at boot time.

The file can include both ranges that are defined explicitly as well as ranges that reference the system page. It has one or more lines in the following format:

ability_list : range_name : range_list

where:

For example:

mem_phys : gpu_mem : syspage:/memory/gpu
interrupt : gpu_int : 12

When the same range name is used for multiple abilities, the ranges associated with the name don't have to be the same. For example, you could add the following line to the file:

setuid : gpu_mem : 9-14

To use the ranges in the policy, you declare the ranges and then use them with the appropriate abilities. For example:

range gpu_mem;
range gpu_int;

allow screen_t self:ability {
    mem_phys: gpu_mem
    interrupt: gpu_int
    setuid: gpu_mem
};
To generate policies that use named ranges, use secpolgenerate with the -r option. To push them, use secpolpush with -r. For example, if the named range file is /proc/boot/secpol_range.txt:
secpolpush -r /proc/boot/secpol_range.txt

You have to use secpolpush to push a policy that uses named ranges because it is the only security policy utility that resolves the named ranges. You can, however, use the secpol utility to view the abilities that have named ranges associated with them.

If any range can't be resolved, unknown abilities are used in the range file, or any other problem with the named range file occurs, the policy is not pushed and it is likely the system won't boot.

Creating asinfo regions in startup suitable for use with named ranges

If you are defining memory regions in startup that you intend to use with named ranges, there are some things to consider to avoid problems.

secpolpush does not merge multiple ranges that happen to be adjacent. The assumption is that each range is a separate entity and you would not be mapping memory that straddles multiple entries. If you attempt to perform such a memory mapping the ability test will fail and you will be denied. Unfortunately, depending on how you define your ranges in startup, you might unintentionally end up in this situation.

If in startup you define a memory region using code such as:

as_add_containing(addr, addr+size-1, AS_ATTR_RAM, "gpu", "memory");

This will add a region called "gpu" but will do so at the deepest level of the memory hierarchy, possibly splitting the region up if it straddles multiple existing regions. For example, the above might result in two memory regions such as /memory/below4G/ram/gpu and /memory/device/ram/gpu.

The preferred way to define the region is to instead use:

unsigned mem = as_find(AS_NULL_OFF, "memory", NULL);
as_add(addr, addr+size-1, AS_ATTR_RAM, "gpu", mem);

This will always create a single region, /memory/gpu. As well as avoiding splitting regions, it also ensures you have a reliable name for the region. In contrast, the first method, even if it does not result in multiple regions, might result in a single region whose name can vary.