This article describes how Android handles the policy compatibility issues with platform OTAs, where new platform SELinux settings may differ from old vendor SELinux settings.
Treble-based SELinux policy design considers a binary distinction
between platform and vendor policy; the scheme becomes
more complicated if vendor partitions generate dependencies, such as
platform
< vendor
< oem
.
In Android 8.0 and higher, SELinux global policy is divided into private and public components. Public components consist of the policy and associated infrastructure, which are guaranteed to be available for a platform version. This policy will be exposed to vendor policy writers to enable vendors to build a vendor policy file, which when combined with the platform-provided policy, results in a fully-functional policy for a device.
- For versioning, the exported platform-public policy will be written as attributes.
- For ease of policy writing, exported types will be transformed into versioned attributes as part of the policy build process. Public types may also be used directly in labeling decisions provided by vendor contexts files.
Android maintains a mapping between exported concrete types in platform policy and the corresponding versioned attributes for each platform version. This ensures that when objects are labeled with a type, it doesn't break behavior guaranteed by the platform-public policy in a previous version. This mapping is maintained by keeping a mapping file up-to-date for each platform version, which keeps attribute membership information for each type exported in public policy.
Object ownership and labeling
When customizing policy in Android 8.0 and higher, ownership must be clearly defined
for each object to keep platform and vendor policy separate. For example, if
the vendor labels /dev/foo
and the platform then labels
/dev/foo
in a subsequent OTA, there will be undefined behavior. For
SELinux, this manifests as a labeling collision. The device node can have only a
single label which resolves to whichever label is applied last. As a result:
- Processes that need access to the unsuccessfully applied label will lose access to the resource.
- Processes that gain access to the file may break because the wrong device node was created.
System properties also have potential for naming collisions that could result in undefined behavior on the system (as well as for SELinux labeling). 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.
In addition to label collisions, SELinux type/attribute names may also collide. A type/attribute name collision will always result in a policy compiler error.
Type/attribute namespacing
SELinux doesn't allow multiple declarations of the same type/attribute. Policy
with duplicate declarations will fail to compilation. To avoid type and
attribute name collisions, all vendor declarations should be namespaced
starting with vendor_
.
type foo, domain; → type vendor_foo, domain;
System property and process labeling ownership
Avoiding labeling collisions is best solved using property namespaces. To easily identify platform properties and avoid name conflicts when renaming or adding exported-platform properties, ensure all vendor properties have their own prefixes:
Property type | Acceptable prefixes |
---|---|
control properties | ctl.vendor. ctl.start$vendor. ctl.stop$vendor. init.svc.vendor.
|
read-writable | vendor. |
read-only | ro.vendor. ro.boot. ro.hardware.
|
persistent | persist.vendor. |
Vendors can continue to use ro.boot.*
(which comes from the kernel
cmdline) and ro.hardware.*
(an obvious hardware-related property).
All the vendor services in init rc files should have vendor.
for services in init rc files of non-system partitions. Similar rules are
applied to the SELinux labels for the vendor properties (vendor_
for the vendor properties).
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 /vendor
policy, a
framework-only OTA update might not be possible.
Vendor (/vendor)
The AOSP SELinux policy already labels parts of vendor
partition
the platform interacts with, which enables writing SELinux rules for platform
processes to be able to talk and/or access parts of 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 vendor
partition:
vendor_file
must be the default label for all files invendor
partition. The platform policy requires this to access passthrough HAL implementations.- All new
exec_types
added invendor
partition through vendor SEPolicy must havevendor_file_type
attribute. This is enforced through neverallows. - To avoid conflicts with future platform/framework updates, avoid labelling
files other than
exec_types
invendor
partition. - 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
), 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 platform and 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 platform and 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/udc
node is labeledsysfs
by default. -
Starting from vendor API level 202504,
/sys/class/udc
is 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.h
for the header file oflibgenfslabelsversion
. -
On Java, use
android.os.SELinux.getGenfsLabelsVersion()
.
Compatibility attributes
SELinux policy is an interaction between source and target types for specific object classes and permissions. Every object (processes, files, etc.) affected by SELinux policy may have only one type, but that type may have multiple attributes.
Policy is written mostly in terms of existing types:
allow source_type target_type:target_class permission(s);
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 may contain policy that gained or lost access previously relied upon. For example:
File_contexts: /sys/A u:object_r:sysfs:s0 Platform: allow p_domain sysfs:class perm; Vendor: allow v_domain sysfs:class perm;
Could be changed to:
File_contexts: /sys/A u:object_r:sysfs_A:s0
Although the vendor policy would remain the same, the v_domain
would lose access due to the lack of policy for the new sysfs_A
type.
By defining a policy in terms of attributes, we can give the underlying object a type that has an attribute corresponding to policy for both the platform and vendor code. This can be done for all types to effectively create an attribute-policy wherein concrete types are never used. In practice, this is required only for the portions of policy that overlap between platform and vendor, which are defined and provided as platform public policy that gets built as part of the vendor policy.
Defining public policy as versioned attributes satisfies two policy compatibility goals:
- Ensure vendor code continues to work after platform update. Achieved by adding attributes to concrete types for objects corresponding to those on which vendor code relied, preserving access.
- Ability to deprecate policy. Achieved by clearly delineating policy sets into attributes that can be removed as soon as the version to which they correspond no longer is supported. Development can continue in the platform, knowing the old policy is still present in the vendor policy and will be automatically removed when/if it upgrades.
Policy writability
To meet the goal of not requiring knowledge of specific version changes for
policy development, Android 8.0 includes a mapping between platform-public
policy types and their attributes. Type foo
is mapped
to attribute foo_vN
, where N
is the
version targeted. vN
corresponds to the
PLATFORM_SEPOLICY_VERSION
build variable and is of the form
MM.NN
, where MM
corresponds to the platform SDK number
and NN
is a platform sepolicy specific version.
Attributes in public policy aren't versioned, but rather exist as an API on which platform and vendor policy can build to keep the interface between the two partitions stable. Both platform and vendor policy writers can continue to write policy as it is written today.
Platform-public policy exported as allow source_foo target_bar:class
perm;
is included as part of the vendor policy. During
compilation (which includes the
corresponding version) it is transformed into the policy that will go to the
vendor portion of the device (shown in the transformed Common Intermediate
Language (CIL)):
(allow source_foo_vN target_bar_vN (class (perm)))
As vendor policy is never ahead of the platform, it shouldn't be concerned with prior versions. However, platform policy will need to know how far back vendor policy is, include attributes to its types, and set policy corresponding to versioned attributes.
Policy diffs
Automatically creating attributes by adding _vN
to the end
of each type does nothing without mapping of attributes to types across version
diffs. Android maintains a mapping between versions for attributes and a
mapping of types to those attributes. This is done in the aforementioned mapping
files with statements, such as (CIL):
(typeattributeset foo_vN (foo))
Platform upgrades
The following section details scenarios for platform upgrades.
Same types
This scenario occurs when an object doesn't change labels in policy versions.
This is the same for source and target types and can be seen with
/dev/binder
, which is labeled binder_device
across all
releases. It is represented in transformed policy as:
binder_device_v1 … binder_device_vN
When upgrading from v1
→ v2
, the platform policy must
contain:
type binder_device; -> (type binder_device) (in CIL)
In the v1 mapping file (CIL):
(typeattributeset binder_device_v1 (binder_device))
In the v2 mapping file (CIL):
(typeattributeset binder_device_v2 (binder_device))
In the v1 vendor policy (CIL):
(typeattribute binder_device_v1) (allow binder_device_v1 …)
In the v2 vendor policy (CIL):
(typeattribute binder_device_v2) (allow binder_device_v2 …)
New types
This scenario occurs when the platform has added a new type, which can happen when adding new features or during policy hardening.
- New feature. When the type is labeling an object that was previously non-existent (such as a new service process), the vendor code didn't previously interact with it directly so no corresponding policy exists. The new attribute corresponding to the type doesn't have an attribute in the previous version, and so wouldn't need an entry in the mapping file targeting that version.
- Policy hardening. When the type represents policy
hardening, the new type attribute must link back to a chain of attributes
corresponding to the previous one (similar to the previous example changing
/sys/A
fromsysfs
tosysfs_A
). Vendor code relies on a rule enabling access tosysfs
, and needs to include that rule as an attribute of the new type.
When upgrading from v1
→ v2
, the platform policy must
contain:
type sysfs_A; -> (type sysfs_A) (in CIL) type sysfs; (type sysfs) (in CIL)
In the v1 mapping file (CIL):
(typeattributeset sysfs_v1 (sysfs sysfs_A))
In the v2 mapping file (CIL):
(typeattributeset sysfs_v2 (sysfs)) (typeattributeset sysfs_A_v2 (sysfs_A))
In the v1 vendor policy (CIL):
(typeattribute sysfs_v1) (allow … sysfs_v1 …)
In the v2 vendor policy (CIL):
(typeattribute sysfs_A_v2) (allow … sysfs_A_v2 …) (typeattribute sysfs_v2) (allow … sysfs_v2 …)
Removed types
This (rare) scenario occurs when a type is removed, which can happen when the underlying object:
- Remains but gets a different label.
- Is removed by the platform.
During policy loosening, a type is removed and the object labeled with that type is given a different, already-existing label. This represents a merging of attribute mappings: The vendor code must still be able to access the underlying object by the attribute it used to possess, but the rest of the system must now be able to access it with its new attribute.
If the attribute to which it has been switched is new, then relabeling is the same as in the new type case, except that when an existing label is used, the addition of the old attribute new type would cause other objects also labeled with this type to be newly accessible. This is essentially what is done by the platform and is deemed to be an acceptable tradeoff to maintain compatibility.
(typeattribute sysfs_v1) (allow … sysfs_v1 …)
Example Version 1: Collapsing types (removing sysfs_A)
When upgrading from v1
→ v2
, the platform policy must
contain:
type sysfs; (type sysfs) (in CIL)
In the v1 mapping file (CIL):
(typeattributeset sysfs_v1 (sysfs)) (type sysfs_A) # in case vendors used the sysfs_A label on objects (typeattributeset sysfs_A_v1 (sysfs sysfs_A))
In the v2 mapping file (CIL):
(typeattributeset sysfs_v2 (sysfs))
In the v1 vendor policy (CIL):
(typeattribute sysfs_A_v1) (allow … sysfs_A_v1 …) (typeattribute sysfs_v1) (allow … sysfs_v1 …)
In the v2 vendor policy (CIL):
(typeattribute sysfs_v2) (allow … sysfs_v2 …)
Example Version 2: Removing completely (foo type)
When upgrading from v1
→ v2
, the platform policy must
contain:
# nothing - we got rid of the type
In the v1 mapping file (CIL):
(type foo) #needed in case vendors used the foo label on objects (typeattributeset foo_v1 (foo))
In the v2 mapping file (CIL):
# nothing - get rid of it
In the v1 vendor policy (CIL):
(typeattribute foo_v1) (allow foo …) (typeattribute sysfs_v1) (allow sysfs_v1 …)
In the v2 vendor policy (CIL):
(typeattribute sysfs_v2) (allow sysfs_v2 …)
New class/permissions
This scenario occurs when a platform upgrade introduces new policy components
that don't exist in previous versions. For example, when Android added the
servicemanager
object manager that created the add, find, and list
permissions, vendor daemons wanting to register with the
servicemanager
needed permissions that weren't
available. In Android 8.0, only the platform policy may add new classes and
permissions.
To allow all domains that could have been created or extended by vendor policy to use the new class without obstruction, the platform policy needs to include a rule similar to:
allow {domain -coredomain} *:new_class perm;
This may even require policy allowing access for all interface (public policy) types, to be sure vendor image gains access. If this results in unacceptable security policy (as it may have with the servicemanager changes), a vendor upgrade could potentially be forced.
Removed class/permissions
This scenario occurs when an object manager is removed (such as the
ZygoteConnection
object manager) and shouldn't cause issues. The
object manager class and permissions could remain defined in policy until the
vendor version no longer uses it. This is done by adding the definitions
to the corresponding mapping file.
Vendor customization for new/relabeled types
New vendor types are at the core of vendor policy development as they are needed to describe new processes, binaries, devices, subsystems, and stored data. As such, it is imperative to allow the creation of vendor-defined types.
As vendor policy is always the oldest on the device, there is no need to
automatically convert all vendor types to attributes in policy. The platform
doesn't rely on anything labeled in vendor policy because the platform has no
knowledge of it; however, the platform will provide the attributes and public
types it uses to interact with objects labeled with these types (such as
domain
, sysfs_type
, etc.). For the platform to
continue to interact correctly with these objects, the attributes and types
must be appropriately applied and specific rules may need to be added to the
customizable domains (such as init
).
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 betweenvendor
andcoredomains
. 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 (exceptinit
andshell 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
coredomains
that need access to vendor binaries should be moved to the vendor partition 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/core
components 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 bysurfaceflinger
Binder service, which apps are permitted to access.hal_omx_hwservice
. This is a HwBinder version of themediacodec
Binder 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
vendor
HALs 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).
Platform-public policy
The platform-public policy is the core of conforming to the Android 8.0
architecture model without simply maintaining the union of platform policies
from v1 and v2. Vendors are exposed to a subset of platform policy that
contains useable types and attributes and rules on those types and attributes
which then becomes part of vendor policy (that is,
vendor_sepolicy.cil
).
Types and rules are automatically translated in the vendor-generated policy
into attribute_vN
such that all platform-provided types
are versioned attributes (however attributes aren't versioned). The platform is
responsible for mapping the concrete types it provides into the appropriate
attributes to ensure that vendor policy continues to function and that the rules
provided for a particular version are included. The combination of
platform-public policy and vendor policy satisfies the Android 8.0 architecture
model goal of allowing independent platform and vendor builds.
Mapping to attribute chains
When using attributes to map to policy versions, a type maps to an attribute or multiple attributes, ensuring objects labeled with the type are accessible via attributes corresponding to their previous types.
Maintaining a goal to hide version information from the policy writer means
automatically generating the versioned attributes and assigning them to the
appropriate types. In the common case of static types, this is straightforward:
type_foo
maps to type_foo_v1
.
For an object label change such as sysfs
→ sysfs_A
or
mediaserver
→ audioserver
, creating this mapping is
non-trivial (and is described in the examples above). Platform policy maintainers
must determine how to create the mapping at transition points for objects, which
requires understanding the relationship between objects and their assigned
labels and determining when this occurs. For backwards compatibility, this
complexity needs to be managed on the platform side, which is the only partition
that may uprev.
Version uprevs
For simplicity, the Android platform releases an sepolicy version when a new
release branch is cut. As described above, the version number is contained in
PLATFORM_SEPOLICY_VERSION
and is of the form MM.nn
,
where MM
corresponds to the SDK value and nn
is a
private value maintained in /platform/system/sepolicy.
For
example, 19.0
for Kitkat, 21.0
for Lollipop,
22.0
for Lollipop-MR1 23.0
for Marshmallow,
24.0
for Nougat, 25.0
for Nougat-MR1,
26.0
for Oreo, 27.0
for Oreo-MR1, and
28.0
for Android 9.
Uprevs aren't always whole numbers. For
example, if an MR bump to a versions necessitates an incompatible change in
system/sepolicy/public
but not an API bump, then that sepolicy
version could be: vN.1
. The version present in a development
branch is a never-to-be-used-in-shipping-devices 10000.0
.
Android may deprecate oldest version when upreving. For input on when to deprecate a version, Android may collect the number of devices with vendor policies running that Android version and still receiving major platform updates. If the number is less than a certain threshold, that version is deprecated.
Performance impact of multiple attributes
As described in https://github.com/SELinuxProject/cil/issues/9, a large number of attributes assigned to a type result in performance issues in the event of a policy cache miss.
This was confirmed to be an issue in Android, so changes were made to Android 8.0 to remove attributes added to the policy by the policy compiler, as well as to remove unused attributes. These changes resolved performance regressions.
system_ext public and product public policy
Starting in Android 11, the system_ext
and product
partitions are allowed to
export their designated public types to the vendor partition. Like platform
public policy, the vendor uses types and rules automatically translated into
the versioned attributes, for example, from type
into
type_N
, where N
is the version
of the platform which the vendor partition is built against.
When the system_ext
and product
partitions are based on the same platform version
N
, the build system generates base mapping files to
system_ext/etc/selinux/mapping/N.cil
and
product/etc/selinux/mapping/N.cil
, which contain identity
mappings from type
to type_N
. The vendor can
access type
with the versioned attribute type_N
.
In case that only the system_ext
and product
partitions are updated, say
N
to N+1
(or later), while the
vendor stays at N
, the vendor may lose access to the
types of the system_ext
and product
partitions. To prevent breakage, the
system_ext
and product
partitions should provide mapping files from concrete
types into type_N
attributes. Each partner is
responsible for maintaining the mapping files, if they are going to support
N
vendor with N+1
(or later)
system_ext
and product
partitions.
To do that, partners are expected to:
- Copy the generated base mapping files from
N
system_ext
andproduct
partitions to their source tree. - Amend the mapping files as needed.
-
Install the
mapping files to
N+1
(or later)system_ext
andproduct
partitions.
For example, suppose that N
system_ext
has one public
type named foo_type
. Then system_ext/etc/selinux/mapping/N.cil
in the N
system_ext
partition will look like:
(typeattributeset foo_type_N (foo_type)) (expandtypeattribute foo_type_N true) (typeattribute foo_type_N)
If bar_type
is added to N+1
system_ext, and
if bar_type
should be mapped to foo_type
for
N
vendor, N.cil
can be updated from
(typeattributeset foo_type_N (foo_type))
to
(typeattributeset foo_type_N (foo_type bar_type))
and then installed to N+1
system_ext's partition.
N
vendor can continue accessing to N+1
system_ext's foo_type
and bar_type
.
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_contexts
cease 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_contexts
are split between two files:plat_file_contexts
- Android platform
file_context
that has no device-specific labels, except for labeling parts of/vendor
partition that must be labeled precisely to ensure proper functioning of the sepolicy files. - Must reside in
system
partition at/system/etc/selinux/plat_file_contexts
on device and be loaded byinit
at the start along with the vendorfile_context
.
- Android platform
vendor_file_contexts
- Device-specific
file_context
built by combiningfile_contexts
found in the directories pointed to byBOARD_SEPOLICY_DIRS
in the device'sBoardconfig.mk
files. - Must be installed at
/vendor/etc/selinux/vendor_file_contexts
invendor
partition and be loaded byinit
at 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_context
that has no device-specific labels. - Must reside in
system
partition at/system/etc/selinux/plat_property_contexts
and be loaded byinit
at the start along with the vendorproperty_contexts
.
- Android platform
vendor_property_contexts
- Device-specific
property_context
built by combiningproperty_contexts
found in the directories pointed to byBOARD_SEPOLICY_DIRS
in device'sBoardconfig.mk
files. - Must reside in
vendor
partition at/vendor/etc/selinux/vendor_property_contexts
and be loaded byinit
at 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_context
for theservicemanager
. Theservice_context
has no device-specific labels. - Must reside in
system
partition at/system/etc/selinux/plat_service_contexts
and be loaded byservicemanager
at the start along with the vendorservice_contexts
.
- Android platform-specific
vendor_service_contexts
- Device-specific
service_context
built by combiningservice_contexts
found in the directories pointed to byBOARD_SEPOLICY_DIRS
in the device'sBoardconfig.mk
files. - Must reside in
vendor
partition at/vendor/etc/selinux/vendor_service_contexts
and be loaded byservicemanager
at the start along with the platformservice_contexts
. - Although
servicemanager
looks for this file at boot time, for a fully compliantTREBLE
device, thevendor_service_contexts
MUST NOT exist. This is because all interaction betweenvendor
andsystem
processes MUST go throughhwservicemanager
/hwbinder
.
- Device-specific
plat_hwservice_contexts
- Android platform
hwservice_context
forhwservicemanager
that has no device-specific labels. - Must reside in
system
partition at/system/etc/selinux/plat_hwservice_contexts
and be loaded byhwservicemanager
at the start along with thevendor_hwservice_contexts
.
- Android platform
vendor_hwservice_contexts
- Device-specific
hwservice_context
built by combininghwservice_contexts
found in the directories pointed to byBOARD_SEPOLICY_DIRS
in the device'sBoardconfig.mk
files. - Must reside in
vendor
partition at/vendor/etc/selinux/vendor_hwservice_contexts
and be loaded byhwservicemanager
at the start along with theplat_service_contexts
.
- Device-specific
vndservice_contexts
- Device-specific
service_context
for thevndservicemanager
built by combiningvndservice_contexts
found in the directories pointed to byBOARD_SEPOLICY_DIRS
in the device'sBoardconfig.mk
. - This file must reside in
vendor
partition at/vendor/etc/selinux/vndservice_contexts
and be loaded byvndservicemanager
at the start.
- Device-specific
Seapp contexts
In Android 8.0, the seapp_contexts
is split between two files:
plat_seapp_contexts
- Android platform
seapp_context
that has no device-specific changes. - Must reside in
system
partition at/system/etc/selinux/plat_seapp_contexts.
- Android platform
vendor_seapp_contexts
- Device-specific extension to platform
seapp_context
built by combiningseapp_contexts
found in the directories pointed to byBOARD_SEPOLICY_DIRS
in the device'sBoardconfig.mk
files. - Must reside in
vendor
partition 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.xml
that has no device-specific changes. - Must reside in
system
partition at/system/etc/selinux/.
- Android platform
- Non-Platform
mac_permissions.xml
- Device-specific extension to platform
mac_permissions.xml
built frommac_permissions.xml
found in the directories pointed to byBOARD_SEPOLICY_DIRS
in the device'sBoardconfig.mk
files. - Must reside in
vendor
partition at/vendor/etc/selinux/.
- Device-specific extension to platform