SELinux is a security mechanism which stops unauthorized access of processes to other processes, actions and filesystems (UNIX's "file" includes all regular files, directories, block devices, character devices, sockets etc.). Every process, file, directory and action is labeled with an SELinux context, then a policy is defined what a context can do to other context. Policy is loaded by kernel or init
on every boot, and anything not defined in policy is denied by kernel. For more details see this answer.
Filesystem contexts are also generated along with policy. On Android both sepolicy
and file_contexts
are saved in rootfs /
or /{system,vendor,odm}/etc/selinux/
directories. Filesystem contexts can be manually changed using chcon
or from file_contexts
using restorecon
. Process can be run with a given context using runcon
. init
also starts all processes with a predefined seclabel
in *.rc
files. Some filesystem contexts are also set on every boot by using restorecon
command in *.rc
files.
Fix Contexts in TWRP fixes filesystem context labels from a saved /file_contexts
file. But if this file is for different device or contains wrong or outdated or incomplete contexts, device may get into bootloop. Better avoid using "Fix Contexts", instead use chcon
or restorecon
manually if necessary. Or replace file_contexts
in recovery ramdisk
with an updated file from your current ROM.
EXAMPLE:
I have around 40000 policy rules on my device, one is:
~# sesearch --allow -s init -t system_data_file -c dir /sys/fs/selinux/policy
Found 1 semantic av rules:
allow init system_data_file : dir { search read open ioctl write create getattr setattr relabelfrom relabelto mounton add_name remove_name rmdir } ;
Out of 2000+ filesystem contexts, one is:
~# grep system_data_file /system/etc/selinux/*contexts
/data(/.*)? u:object_r:system_data_file:s0
SELinux context of init
process:
~# ps -p 1 -o pid,cmd,label
PID CMD LABEL
1 /init u:r:init:s0
SELinux context of directory containing system settings:
~# ls -dZ /data/system
u:object_r:system_data_file:s0 /data/system
So if /data/system
is labeled with wrong context, init
won't be able to perform search
, read
and open
operations on the the directory and the device may bootloop.
DAC vs MAC:
SELinux is an implementation of Mandatory Access Control (MAC). Discretionary Access Control (DAC) achieves the same goal in less aggressive way by assigning UIDs/GIDs to processes and files:
~# ls -ld /data /data/system
drwxrwx--x 41 system system 4096 Oct 21 17:40 /data
drwxrwxr-x 21 system system 3488 Nov 9 13:36 /data/system
Permission mode and ownership explains that only processes running with UID or GID 1000
(system
) will be able to read and write to the directory and normal apps (with UIDs/GIDs in range 10000
to 19999
) are not allowed to read system settings.
A drawback of DAC is that it's allowed by default and has a Super User (root user with UID 0
is allowed to do anything). While MAC is denied by default and there is no Super Context, so it's less prone to exploits. Root user's authorities are also divided in capabilities to follow the principle of least privileges. Combined together, both DAC and MAC provide a more robust isolation, protection and sandboxing.