SELinux depends upon labels to match actions and policies. Labels determine what is allowed. Sockets, files, and processes all have labels in SELinux. SELinux decisions are based fundamentally on labels assigned to these objects and the policy defining how they may interact. In SELinux, a label takes the form: user:role:type:mls_level, where the type is the primary component of the access decisions, which may be modified by the other sections components which make up the label. The objects are mapped to classes and the different types of access for each class are represented by permissions.
The policy rules come in the form: allow domains types:classes permissions;, where:
Domain - A label for the process or set of processes. Also called a domain type as it is just a type for a process.
Type - A label for the object (e.g. file, socket) or set of objects.
Class - The kind of object (e.g. file, socket) being accessed.
Permission - The operation (e.g. read, write) being performed.
And so an example use of this would follow the structure:
allow appdomain app_data_file:file rw_file_perms;
This says that all application domains are allowed to read and write files labeled app_data_file. Note that this rule relies upon macros defined in the global_macros file, and other helpful macros can also be found in the te_macros file, both of which can be found in the external/sepolicy directory in the AOSP source tree. Macros are provided for common groupings of classes, permissions and rules, and should be used whenever possible to help reduce the likelihood of failures due to denials on related permissions.
In addition to individually listing domains or types in a rule, one can also refer to a set of domains or types via an attribute. An attribute is simply a name for a set of domains or types. Each domain or type can be associated with any number of attributes. When a rule is written that specifies an attribute name, that name is automatically expanded to the list of domains or types associated with the attribute. For example, the domain attribute is associated with all process domains, and the file_type attribute is associated with all file types.
Use the syntax above to create avc rules that comprise the essence of an SELinux policy. A rule takes the form:
<rule variant> <source_types> <target_types> : <classes> <permissions>
The rule indicates what should happen when a subject labeled with any of the source_types attempts an action corresponding to any of the permissions on an object with any of the class classes which has any of the target_types label. The most common example of one of these rules is an allow rule, e.g.:
allow domain null_device:chr_file { open };
This rule allows a process with any domain associated with the ‘domain’ attribute to take the action described by the permission ‘open’ on an object of class ‘chr_file’ (character device file) that has the target_type label of ‘null_device.’ In practice, this rule may be extended to include other permissions:
allow domain null_device:chr_file { getattr open read ioctl lock
append write};
When combined with the knowledge that ‘domain’ is an attribute assigned to all process domains and that null_device is the label for the character device /dev/null, this rule basically permits reading and writing to /dev/null.
A domain generally corresponds to a process and will have a label associated with it.
For example, a typical Android app is running in its own process and has the label of untrusted_app that grants it certain restricted permissions.
Platform apps built into the system run under a separate label and are granted a distinct set of permissions. System UID apps that are part of the core Android system run under the system_app label for yet another set of privileges.
Access to the following generic labels should never be directly allowed to domains; instead, a more specific type should be created for the object or objects:
socket_device
device
block_device
default_service
system_data_file
tmpfs
Source: SELinux concepts
For more details, see: Security-Enhanced Linux in Android
Implementing SELinux