This page describes how Android handles the policy compatibility issues with platform over-the-air (OTA) updates, where new platform SELinux settings might differ from old vendor SELinux settings.
Object ownership and labeling
Ownership must be clearly defined for each object to keep platform and vendor
policy separate. For example, if the vendor policy labels /dev/foo
and the platform policy labels /dev/foo in a subsequent OTA, there
is undefined behavior like an unexpected denial, or more critically, a boot
failure. For SELinux, this manifests as a labeling collision. The device node
can have only a single label that resolves to whichever label is applied last.
As a result:
- Processes that need access to the unsuccessfully applied label loses access to the resource.
- Processes that gain access to the file might break because the wrong device node was created.
Collisions between platform and vendor labels can occur for any object that has an SELinux label, including properties, services, processes, files, and sockets. To avoid these issues, clearly define ownership of these objects.
Type/attribute namespacing
In addition to label collisions, SELinux type and attribute names can also
collide. SELinux doesn't allow multiple declarations of the same types and
attributes. A policy with duplicate declarations fails to compile. To avoid type
and attribute name collisions, all vendor declarations are highly recommended to
start with the vendor_ prefix. For example, vendors should use
type vendor_foo, domain; instead of type foo, domain;.
File ownership
Preventing collisions for files is challenging because platform and vendor policy both commonly provide labels for all filesystems. Unlike type naming, namespacing of files isn't practical since many of them are created by the kernel. To prevent these collisions, follow the naming guidance for filesystems in this section. For Android 8.0, these are recommendations without technical enforcement. In the future, these recommendations will be enforced by the Vendor Test Suite (VTS).
System (/system)
Only the system image must provide labels for /system components
through file_contexts, service_contexts, etc. If labels
for /system components are added in the vendor policy, a
framework-only OTA update might not be possible.
Vendor (/vendor)
The AOSP SELinux policy already labels parts of the vendor
partition the platform interacts with, which enables writing SELinux rules for
platform processes to be able to talk or access parts of the vendor
partition. Examples:
| /vendor path | Platform-provided label | Platform processes depending on the label |
|---|---|---|
/vendor(/.*)?
|
vendor_file
|
All HAL clients in framework, ueventd, etc.
|
/vendor/framework(/.*)?
|
vendor_framework_file
|
dex2oat, appdomain, etc.
|
/vendor/app(/.*)?
|
vendor_app_file
|
dex2oat, installd, idmap, etc.
|
/vendor/overlay(/.*)
|
vendor_overlay_file
|
system_server, zygote, idmap, etc.
|
As a result, specific rules must be followed (enforced through
neverallows) when labelling additional files in the
vendor partition:
vendor_filemust be the default label for all files in thevendorpartition. The platform policy requires this to access passthrough HAL implementations.- All new
exec_typesadded in thevendorpartition through the vendor policy must havevendor_file_typeattribute. This is enforced through neverallows. - To avoid conflicts with future platform/framework updates, avoid labelling
files other than
exec_typesin thevendorpartition. - All library dependencies for AOSP-identified same process HALs must be
labelled as
same_process_hal_file.
Procfs (/proc)
Files in /proc may be labeled using only the genfscon
label. In Android 7.0, both the
platform
and vendor
policy used genfscon to label files in procfs.
Recommendation: Only platform policy labels /proc.
If vendor processes need access to files in /proc that are
currently labeled with the default label (proc), the vendor policy
shouldn't explicitly label them and should instead use the generic
proc type to add rules for vendor domains. This allows the platform
updates to accommodate future kernel interfaces exposed through
procfs and label them explicitly as needed.
Debugfs (/sys/kernel/debug)
Debugfs can be labeled in both file_contexts and
genfscon. In Android 7.0 to Android 10, both platform and vendor label
debugfs.
In Android 11, debugfs can't be
accessed or mounted on production devices. Device manufacturers should
remove debugfs.
Tracefs (/sys/kernel/debug/tracing)
Tracefs can be labeled in both file_contexts and
genfscon. In Android 7.0, only the platform labels
tracefs.
Recommendation: Only platform may label tracefs.
Sysfs (/sys)
Files in /sys may be labeled using both file_contexts
and genfscon. In Android 7.0, both the platform and the vendor use
genfscon to label files in sysfs.
Recommendation: The platform may label sysfs
nodes that aren't device-specific. Otherwise, only vendor may label files.
tmpfs (/dev)
Files in /dev may be labeled in file_contexts. In
Android 7.0, both the platform and the vendor label files here.
Recommendation: Vendor may label only files in
/dev/vendor (for example, /dev/vendor/foo,
/dev/vendor/socket/bar).
Rootfs (/)
Files in / may be labeled in file_contexts. In Android
7.0, both platform and vendor label files here.
Recommendation: Only system may label files in /.
Data (/data)
Data is labeled through a combination of file_contexts and
seapp_contexts.
Recommendation: Disallow vendor labeling outside
/data/vendor. Only platform may label other parts of
/data.
Genfs labels version
Starting with vendor API level 202504, newer SELinux
labels assigned with genfscon in
system/sepolicy/compat/plat_sepolicy_genfs_ver.cil are
optional for older vendor partitions. This allows older
vendor partitions to keep their existing SEPolicy implementation.
This is controlled by the Makefile variable BOARD_GENFS_LABELS_VERSION
which is stored in /vendor/etc/selinux/genfs_labels_version.txt.
Example:
-
In vendor API level 202404, the
/sys/class/udcnode is labeledsysfsby default. -
Starting from vendor API level 202504,
/sys/class/udcis labeledsysfs_udc.
However, /sys/class/udc might be in use by vendor
partitions using API level 202404, either with the default sysfs
label or a vendor-specific label. Unconditionally labeling
/sys/class/udc as sysfs_udc could break compatibility
with these vendor partitions. By checking
BOARD_GENFS_LABELS_VERSION, the platform keeps using the previous
labels and permissions for the older vendor partitions.
BOARD_GENFS_LABELS_VERSION can be greater than or equal to vendor API level. For
instance, vendor partitions using API level 202404 can set
BOARD_GENFS_LABELS_VERSION to 202504 to adopt new labels introduced
in 202504. See the list of
202504-specific genfs labels.
When labeling genfscon nodes, the platform must consider older
vendor partitions and implement fallback mechanisms for
compatibility when needed. The platform can use platform-only libraries to query
the genfs labels version.
-
On native, use
libgenfslabelsversion. Seegenfslabelsversion.hfor the header file oflibgenfslabelsversion. -
On Java, use
android.os.SELinux.getGenfsLabelsVersion().
Platform-public policy
The platform SELinux policy is divided into private and public. The
platform-public policy consists of types and attributes that are always
available for a vendor API level,
acting as an API between platform and vendor. This policy is exposed to vendor
policy writers to enable vendors to build vendor policy files, which when
combined with the platform-private policy, results in a fully functional policy
for a device. The platform-public policy is defined in
system/sepolicy/public.
For example, a type vendor_init, representing the init process in
the context of vendor, is defined under
system/sepolicy/public/vendor_init.te:
type vendor_init, domain;
Vendors can refer to the type vendor_init to write custom policy
rules:
# Allow vendor_init to set vendor_audio_prop in vendor's init scripts
set_prop(vendor_init, vendor_audio_prop)Compatibility attributes
SELinux policy is an interaction between source and target types for specific object classes and permissions. Every object (for example, processes, files) affected by SELinux policy can have only one type, but that type might have multiple attributes.
The policy is written mostly in terms of existing types. Here, both
vendor_init and debugfs are types:
allow vendor_init debugfs:dir { mounton };
This works because the policy was written with knowledge of all types. However,
if the vendor policy and platform policy use specific types, and the label of a
specific object changes in only one of those policies, the other might contain
policy that gained or lost access previously relied upon. For example, suppose
that the platform policy labels sysfs nodes as sysfs:
/sys(/.*)? u:object_r:sysfs:s0
The vendor policy grants access to /sys/usb, labeled as
sysfs:
allow vendor_init sysfs:chr_file rw_file_perms;
If the platform policy is changed to label /sys/usb as
sysfs_usb, the vendor policy remains the same, but
vendor_init loses access to /sys/usb due to the lack
of policy for the new sysfs_usb type:
/sys/usb u:object_r:sysfs_usb:s0
To solve this issue, Android introduces a concept of versioned attributes. At compile time, the build system automatically translates platform public types used in the vendor policy into these versioned attributes. This translation is enabled by mapping files that associate a versioned attribute with one or more public types from the platform.
For example, suppose that /sys/usb is labeled as sysfs
in 202504 platform policy, and 202504 vendor policy grants
vendor_init access to /sys/usb. In this case:
-
The vendor policy writes a rule
allow vendor_init sysfs:chr_file rw_file_perms;, because/sys/usbis labeled assysfsin 202504 platform policy. When the build system compiles vendor policy, it automatically translates the rule intoallow vendor_init_202504 sysfs_202504:chr_file rw_file_perms;. The attributesvendor_init_202504andsysfs_202504correspond to the typesvendor_initandsysfs, which are the types defined by the platform. -
The build system generates an identity mapping file
/system/etc/selinux/mapping/202504.cil. As both thesystemandvendorpartitions use the same202504version, the mapping file contains identity mappings fromtype_202504totype. For example,vendor_init_202504is mapped tovendor_init, andsysfs_202504is mapped tosysfs:(typeattributeset sysfs_202504 (sysfs)) (typeattributeset vendor_init_202504 (vendor_init)) ...
When the version is bumped from 202504 to 202604, a new mapping file for 202504
vendor partitions is created under
system/sepolicy/private/compat/202504/202504.cil, which is
installed to /system/etc/selinux/mapping/202504.cil for the 202604
or newer system partitions. Initially, this mapping file contains
identity mappings, as previously described. If a new label sysfs_usb
for /sys/usb is added to the 202604 platform policy, the mapping
file is updated to map sysfs_202504 to sysfs_usb:
(typeattributeset sysfs_202504 (sysfs sysfs_usb)) (typeattributeset vendor_init_202504 (vendor_init)) ...
This update allows the converted vendor policy rule allow
vendor_init_202504 sysfs_202504:chr_file rw_file_perms; to automatically
grant vendor_init access to the new sysfs_usb type.
To maintain compatibility with older vendor partitions, whenever a
new public type is added, that type must be mapped to at least one of versioned
attributes in the mapping file system/sepolicy/private/compat/ver/ver.cil,
or be listed under system/sepolicy/private/compat/ver/ver.ignore.cil
to state that there is no matching type in the previous vendor versions.
The combination of the platform policy, the vendor policy, and the mapping file allows the system to update without updating the vendor policy. Also the conversion into the versioned attributes happens automatically, so the vendor policy doesn't need to take care of the versioning, keeping using the public types as is.
system_ext public and product public policy
Starting in Android 11, the system_ext and the product
partitions are allowed to export their designated public types to the
vendor partition. Like the platform public policy, the vendor
policy uses types and rules automatically translated into the versioned
attributes, for example, from type into
type_ver, where ver is the vendor API level
of the vendor partition.
When the system_ext and the product partitions are
based on the same platform version ver, the build system generates
base mapping files to system_ext/etc/selinux/mapping/ver.cil
and product/etc/selinux/mapping/ver.cil, which contain
identity mappings from type to type_ver.
The vendor policy can access type with the versioned attribute
type_ver.
In case that only the system_ext and the product
partitions are updated, say ver to ver+1 (or later), while
the vendor partition stays at ver, the vendor policy
might lose access to the types of the system_ext and the
product partitions. To prevent breakage, the
system_ext and the product partitions should provide
mapping files from concrete types into type_ver
attributes. Each partner is responsible for maintaining the mapping
files, if they support ver vendor partition with
ver+1 (or later) system_ext and product
partitions.
To install mapping files to the system_ext and the product
partitions, device implementers, or vendors are expected to:
- Copy the generated base mapping files from ver
system_extandproductpartitions to their source tree. - Amend the mapping files as needed.
-
Install the
mapping files to ver+1 (or later)
system_extandproductpartitions.
For example, suppose that the 202504 system_ext partition has one
public type named foo_type. Then
system_ext/etc/selinux/mapping/202504.cil
in the 202504 system_ext partition looks like this:
(typeattributeset foo_type_202504 (foo_type)) (expandtypeattribute foo_type_202504 true) (typeattribute foo_type_202504)
If bar_type is added to the 202604 system_ext, and if
bar_type should be mapped to foo_type for the 202504
vendor partition, 202504.cil can be updated from
(typeattributeset foo_type_202504 (foo_type)) to
(typeattributeset foo_type_202504 (foo_type bar_type))
and then installed to the 202604 system_ext partition. The 202504
vendor partition can continue accessing to the 202604
system_ext's foo_type and bar_type.
Attribute changes for Android 9
Devices upgrading to Android 9 can use the following attributes, but devices launching with Android 9 must not.
Violator attributes
Android 9 includes these domain-related attributes:
data_between_core_and_vendor_violators. Attribute for all domains that violate the requirement of not sharing files by path betweenvendorandcoredomains. Platform and vendor processes shouldn't use on-disk files to communicate (unstable ABI). Recommendation:- Vendor code should use
/data/vendor. - System shouldn't use
/data/vendor.
- Vendor code should use
system_executes_vendor_violators. Attribute for all system domains (exceptinitandshell domains) that violate the requirement of not executing vendor binaries. Execution of vendor binaries has unstable API. Platform shouldn't execute vendor binaries directly. Recommendation:- Such platform dependencies on vendor binaries must be behind HIDL HALs.
OR
coredomainsthat need access to vendor binaries should be moved to thevendorpartition and thus, stop beingcoredomain.
- Such platform dependencies on vendor binaries must be behind HIDL HALs.
Untrusted attributes
Untrusted apps that host arbitrary code shouldn't have access to HwBinder services, except those considered sufficiently safe for access from such apps (see safe services below). The two main reasons for this are:
- HwBinder servers don't perform client authentication because HIDL currently doesn't expose caller UID information. Even if HIDL did expose such data, many HwBinder services either operate at a level below that of apps (such as, HALs) or must not rely on app identity for authorization. Thus, to be safe, the default assumption is that every HwBinder service treats all its clients as equally authorized to perform operations offered by the service.
- HAL servers (a subset of HwBinder services) contain code with higher
incidence rate of security issues than
system/corecomponents and have access to the lower layers of the stack (all the way down to hardware) thus increasing opportunities for bypassing the Android security model.
Safe services
Safe services include:
same_process_hwservice. These services (by definition) run in the process of the client and thus have the same access as the client domain in which the process runs.coredomain_hwservice. These services don't pose risks associated with reason #2.hal_configstore_ISurfaceFlingerConfigs. This service is specifically designed for use by any domain.hal_graphics_allocator_hwservice. These operations are also offered bysurfaceflingerBinder service, which apps are permitted to access.hal_omx_hwservice. This is a HwBinder version of themediacodecBinder service, which apps are permitted to access.hal_codec2_hwservice. This is a newer version ofhal_omx_hwservice.
Useable attributes
All hwservices not considered safe have the attribute
untrusted_app_visible_hwservice. The corresponding HAL servers have
the attribute untrusted_app_visible_halserver. Devices launching
with Android 9 MUST NOT use either
untrusted attribute.
Recommendation:
- Untrusted apps should instead talk to a system service that talks to the
vendor HIDL HAL. For example, apps can talk to
binderservicedomain, thenmediaserver(which is abinderservicedomain) in turn talks to thehal_graphics_allocator.OR
- Apps that need direct access to
vendorHALs should have their own vendor-defined sepolicy domain.
File attribute tests
Android 9 includes build time tests that ensure all files in specific
locations have the appropriate attributes (such as, all files in
sysfs have the required sysfs_type attribute).
SELinux contexts labeling
To support the distinction between platform and vendor sepolicy, the system builds SELinux context files differently to keep them separate.
File contexts
Android 8.0 introduced the following changes for file_contexts:
- To avoid additional compilation overhead on device during boot,
file_contextscease to exist in the binary form. Instead, they are readable, regular expression text file such as{property, service}_contexts(as they were pre-7.0). - The
file_contextsare split between two files:plat_file_contexts- Android platform
file_contextthat has no device-specific labels, except for labeling parts of/vendorpartition that must be labeled precisely to ensure proper functioning of the sepolicy files. - Must reside in
systempartition at/system/etc/selinux/plat_file_contextson device and be loaded byinitat the start along with the vendorfile_context.
- Android platform
vendor_file_contexts- Device-specific
file_contextbuilt by combiningfile_contextsfound in the directories pointed to byBOARD_SEPOLICY_DIRSin the device'sBoardconfig.mkfiles. - Must be installed at
/vendor/etc/selinux/vendor_file_contextsinvendorpartition and be loaded byinitat the start along with the platformfile_context.
- Device-specific
Property contexts
In Android 8.0, the property_contexts is split between two files:
plat_property_contexts- Android platform
property_contextthat has no device-specific labels. - Must reside in
systempartition at/system/etc/selinux/plat_property_contextsand be loaded byinitat the start along with the vendorproperty_contexts.
- Android platform
vendor_property_contexts- Device-specific
property_contextbuilt by combiningproperty_contextsfound in the directories pointed to byBOARD_SEPOLICY_DIRSin device'sBoardconfig.mkfiles. - Must reside in
vendorpartition at/vendor/etc/selinux/vendor_property_contextsand be loaded byinitat the start along with the platformproperty_context
- Device-specific
Service contexts
In Android 8.0, the service_contexts is split between the following
files:
plat_service_contexts- Android platform-specific
service_contextfor theservicemanager. Theservice_contexthas no device-specific labels. - Must reside in
systempartition at/system/etc/selinux/plat_service_contextsand be loaded byservicemanagerat the start along with the vendorservice_contexts.
- Android platform-specific
vendor_service_contexts- Device-specific
service_contextbuilt by combiningservice_contextsfound in the directories pointed to byBOARD_SEPOLICY_DIRSin the device'sBoardconfig.mkfiles. - Must reside in
vendorpartition at/vendor/etc/selinux/vendor_service_contextsand be loaded byservicemanagerat the start along with the platformservice_contexts. - Although
servicemanagerlooks for this file at boot time, for a fully compliantTREBLEdevice, thevendor_service_contextsMUST NOT exist. This is because all interaction betweenvendorandsystemprocesses MUST go throughhwservicemanager/hwbinder.
- Device-specific
plat_hwservice_contexts- Android platform
hwservice_contextforhwservicemanagerthat has no device-specific labels. - Must reside in
systempartition at/system/etc/selinux/plat_hwservice_contextsand be loaded byhwservicemanagerat the start along with thevendor_hwservice_contexts.
- Android platform
vendor_hwservice_contexts- Device-specific
hwservice_contextbuilt by combininghwservice_contextsfound in the directories pointed to byBOARD_SEPOLICY_DIRSin the device'sBoardconfig.mkfiles. - Must reside in
vendorpartition at/vendor/etc/selinux/vendor_hwservice_contextsand be loaded byhwservicemanagerat the start along with theplat_service_contexts.
- Device-specific
vndservice_contexts- Device-specific
service_contextfor thevndservicemanagerbuilt by combiningvndservice_contextsfound in the directories pointed to byBOARD_SEPOLICY_DIRSin the device'sBoardconfig.mk. - This file must reside in
vendorpartition at/vendor/etc/selinux/vndservice_contextsand be loaded byvndservicemanagerat the start.
- Device-specific
Seapp contexts
In Android 8.0, the seapp_contexts is split between two files:
plat_seapp_contexts- Android platform
seapp_contextthat has no device-specific changes. - Must reside in
systempartition at/system/etc/selinux/plat_seapp_contexts.
- Android platform
vendor_seapp_contexts- Device-specific extension to platform
seapp_contextbuilt by combiningseapp_contextsfound in the directories pointed to byBOARD_SEPOLICY_DIRSin the device'sBoardconfig.mkfiles. - Must reside in
vendorpartition at/vendor/etc/selinux/vendor_seapp_contexts.
- Device-specific extension to platform
MAC permissions
In Android 8.0, the mac_permissions.xml is split between two files:
- Platform
mac_permissions.xml- Android platform
mac_permissions.xmlthat has no device-specific changes. - Must reside in
systempartition at/system/etc/selinux/.
- Android platform
- Non-Platform
mac_permissions.xml- Device-specific extension to platform
mac_permissions.xmlbuilt frommac_permissions.xmlfound in the directories pointed to byBOARD_SEPOLICY_DIRSin the device'sBoardconfig.mkfiles. - Must reside in
vendorpartition at/vendor/etc/selinux/.
- Device-specific extension to platform