В этой статье описывается, как Android решает проблемы совместимости политики с платформами OTA, когда настройки SELinux новой платформы могут отличаться от настроек SELinux старого поставщика.
Разработка политики SELinux на основе Treble учитывает бинарное различие между политикой платформы и поставщика ; схема усложняется, если разделы поставщика генерируют зависимости, например, platform
< vendor
< oem
.
В Android 8.0 и более поздних версиях глобальная политика SELinux разделена на частный и общедоступный компоненты. Публичные компоненты состоят из политики и связанной с ней инфраструктуры, которые гарантированно доступны для версии платформы. Эта политика будет доступна авторам политик поставщиков, чтобы они могли создать файл политики поставщика, который в сочетании с политикой, предоставляемой платформой, приводит к созданию полнофункциональной политики для устройства.
- Для управления версиями экспортированная общедоступная политика платформы будет записана в виде атрибутов .
- Для упрощения написания политики экспортированные типы будут преобразованы в версионные атрибуты в рамках процесса построения политики. Открытые типы также могут использоваться непосредственно при принятии решений о маркировке, предоставляемых файлами контекстов поставщика.
Android поддерживает сопоставление между экспортированными конкретными типами в политике платформы и соответствующими атрибутами версий для каждой версии платформы. Это гарантирует, что когда объекты помечаются типом, это не нарушает поведение, гарантированное общедоступной политикой платформы в предыдущей версии. Это сопоставление поддерживается за счет обновления файла сопоставления для каждой версии платформы , в котором сохраняется информация о членстве атрибутов для каждого типа, экспортируемого в общедоступную политику.
Владение объектом и маркировка
При настройке политики в Android 8.0 и более поздних версиях необходимо четко определить право собственности для каждого объекта, чтобы политика платформы и политика поставщика были разделены. Например, если поставщик маркирует /dev/foo
, а платформа затем маркирует /dev/foo
в последующем OTA, поведение будет неопределенным. Для SELinux это проявляется как конфликт меток. Узел устройства может иметь только одну метку, которая соответствует той метке, которая была применена последней. Как результат:
- Процессы, которым требуется доступ к неудачно примененной метке, потеряют доступ к ресурсу.
- Процессы, получающие доступ к файлу, могут прерваться, поскольку был создан неправильный узел устройства.
Системные свойства также могут вызывать конфликты имен, которые могут привести к неопределенному поведению системы (а также к маркировке SELinux). Конфликты между метками платформы и поставщика могут возникнуть для любого объекта, имеющего метку SELinux, включая свойства, службы, процессы, файлы и сокеты. Чтобы избежать этих проблем, четко определите право собственности на эти объекты.
Помимо конфликтов меток, могут также конфликтовать имена типов/атрибутов SELinux. Конфликт имен типов и атрибутов всегда приводит к ошибке компилятора политики.
Пространство имен типа/атрибута
SELinux не допускает несколько объявлений одного и того же типа/атрибута. Политика с повторяющимися объявлениями не будет скомпилирована. Чтобы избежать конфликтов имен типов и атрибутов, все объявления поставщиков должны располагаться в пространстве имен, начиная с vendor_
.
type foo, domain; → type vendor_foo, domain;
Владение маркировкой системных свойств и процессов
Избежать конфликтов маркировки лучше всего с помощью пространств имен свойств. Чтобы легко идентифицировать свойства платформы и избежать конфликтов имен при переименовании или добавлении свойств экспортированной платформы, убедитесь, что все свойства поставщика имеют свои собственные префиксы:
Тип недвижимости | Допустимые префиксы |
---|---|
свойства управления | ctl.vendor. ctl.start$vendor. ctl.stop$vendor. init.svc.vendor. |
доступный для чтения и записи | vendor. |
только для чтения | ro.vendor. ro.boot. ro.hardware. |
настойчивый | persist.vendor. |
Поставщики могут продолжать использовать ro.boot.*
(который поступает из командной строки ядра) и ro.hardware.*
(очевидное свойство, связанное с оборудованием).
Все службы поставщика в файлах init rc должны иметь vendor.
для служб в файлах init rc несистемных разделов. Аналогичные правила применяются к меткам SELinux для свойств поставщика ( vendor_
для свойств поставщика).
Владение файлом
Предотвращение коллизий файлов является сложной задачей, поскольку политика платформы и поставщика обычно предоставляют метки для всех файловых систем. В отличие от именования типов, пространство имен файлов нецелесообразно, поскольку многие из них создаются ядром. Чтобы предотвратить эти конфликты, следуйте инструкциям по именованию файловых систем в этом разделе. Для Android 8.0 это рекомендации без технического применения. В будущем эти рекомендации будут реализованы с помощью Vendor Test Suite (VTS).
Система (/система)
Только образ системы должен предоставлять метки для компонентов /system
через file_contexts
, service_contexts
и т. д. Если метки для компонентов /system
добавляются в политику /vendor
, OTA-обновление только для платформы может оказаться невозможным.
Продавец (/vendor)
Политика AOSP SELinux уже помечает части раздела vendor
с которыми взаимодействует платформа, что позволяет писать правила SELinux для процессов платформы, чтобы они могли общаться и/или получать доступ к частям раздела vendor
. Примеры:
/vendor | Ярлык, предоставленный платформой | Платформенные процессы в зависимости от лейбла |
---|---|---|
/vendor(/. * )? | vendor_file | Все клиенты HAL в framework, ueventd и т. д. |
/vendor/framework(/. * )? | vendor_framework_file | dex2oat , appdomain и т. д. |
/vendor/app(/. * )? | vendor_app_file | dex2oat , installd , idmap и т. д. |
/vendor/overlay(/. * ) | vendor_overlay_file | system_server , zygote , idmap и т. д. |
В результате при маркировке дополнительных файлов в разделе vendor
необходимо соблюдать определенные правила (обеспечиваемые через neverallows
):
-
vendor_file
должен быть меткой по умолчанию для всех файлов в разделеvendor
. Политика платформы требует этого для доступа к сквозным реализациям HAL. - Все новые
exec_types
, добавленные в разделvendor
через SEPolicy поставщика, должны иметьvendor_file_type
. Это обеспечивается через Neverallows. - Чтобы избежать конфликтов с будущими обновлениями платформы/фреймворка, не помечайте файлы, отличные от
exec_types
в разделеvendor
. - Все зависимости библиотеки для HAL одного и того же процесса, идентифицированного AOSP, должны быть помечены как
same_process_hal_file.
Процфс (/прок)
Файлы в /proc
могут быть помечены только меткой genfscon
. В Android 7.0 политика платформы и поставщика использовала genfscon
для маркировки файлов в procfs
.
Рекомендация: только метки политики платформы /proc
. Если процессам vendor
требуется доступ к файлам в /proc
, которые в настоящее время помечены меткой по умолчанию ( proc
), политика поставщика не должна явно помечать их и вместо этого должна использовать общий тип proc
для добавления правил для доменов поставщиков. Это позволяет обновлениям платформы учитывать будущие интерфейсы ядра, предоставляемые через procfs
, и явно маркировать их по мере необходимости.
Debugfs (/sys/kernel/debug)
Debugfs
могут быть помечены как в file_contexts
, так и в genfscon
. В версиях от Android 7.0 до Android 10 и платформа, и поставщик отмечают debugfs
.
В Android 11 debugfs
невозможно получить доступ или смонтировать их на производственных устройствах. Производители устройств должны удалить debugfs
.
Tracefs (/sys/kernel/debug/tracing)
Tracefs
могут быть помечены как в file_contexts
, так и в genfscon
. В Android 7.0 только платформа помечает tracefs
.
Рекомендация: только платформа может помечать tracefs
.
Системная файловая система (/sys)
Файлы в /sys
могут быть помечены как file_contexts
, так и genfscon
. В Android 7.0 и платформа, и поставщик используют genfscon
для маркировки файлов в sysfs
.
Рекомендация. Платформа может маркировать узлы sysfs
, которые не относятся к конкретному устройству. В противном случае только поставщик может маркировать файлы.
tmpfs (/dev)
Файлы в /dev
могут быть помечены как file_contexts
. В Android 7.0 здесь находятся файлы меток как платформы, так и поставщика.
Рекомендация: Поставщик может маркировать только файлы в /dev/vendor
(например, /dev/vendor/foo
, /dev/vendor/socket/bar
).
Рутфс (/)
Файлы в /
могут быть помечены в file_contexts
. В Android 7.0 здесь находятся файлы меток как платформы, так и поставщика.
Рекомендация: только система может помечать файлы в /
.
Данные (/данные)
Данные помечаются с помощью комбинации file_contexts
и seapp_contexts
.
Рекомендация: запретить маркировку поставщиков за пределами /data/vendor
. Только платформа может маркировать другие части /data
.
Версия ярлыков Genfs
Начиная с уровня 202504 API поставщика , новые метки SELinux, назначенные с помощью genfscon
в system/sepolicy/compat/plat_sepolicy_genfs_{ver}.cil
являются необязательными для разделов старых поставщиков. Это позволяет разделам старых поставщиков сохранять существующую реализацию SEPolicy. Это контролируется переменной Makefile BOARD_GENFS_LABELS_VERSION
, которая хранится в /vendor/etc/selinux/genfs_labels_version.txt
.
Пример:
- На уровне API поставщика 202404 узел
/sys/class/udc
по умолчанию помечен какsysfs
. - Начиная с уровня API поставщика 202504,
/sys/class/udc
помечается какsysfs_udc
.
Однако /sys/class/udc
может использоваться разделами поставщика с использованием уровня API 202404 либо с меткой sysfs
по умолчанию, либо с меткой, зависящей от поставщика. Безоговорочное обозначение /sys/class/udc
как sysfs_udc
может привести к нарушению совместимости с разделами этих поставщиков. При проверке BOARD_GENFS_LABELS_VERSION
платформа продолжает использовать предыдущие метки и разрешения для разделов старого поставщика.
BOARD_GENFS_LABELS_VERSION
может быть больше или равен уровню API поставщика. Например, разделы поставщиков, использующие уровень API 202404, могут установить для BOARD_GENFS_LABELS_VERSION
значение 202504, чтобы принять новые метки, представленные в 202504. См. список меток genfs, специфичных для 202504 .
При маркировке узлов genfscon
платформа должна учитывать разделы старых поставщиков и при необходимости реализовывать резервные механизмы для обеспечения совместимости. Платформа может использовать библиотеки только для платформы для запроса версии меток genfs.
- В собственном коде используйте
libgenfslabelsversion
. См.genfslabelsversion.h
для заголовочного файлаlibgenfslabelsversion
. - В Java используйте
android.os.SELinux.getGenfsLabelsVersion()
.
Атрибуты совместимости
Политика SELinux — это взаимодействие между исходными и целевыми типами для определенных классов объектов и разрешений. Каждый объект (процессы, файлы и т. д.), на который влияет политика SELinux, может иметь только один тип, но этот тип может иметь несколько атрибутов.
Политика написана в основном с использованием существующих типов:
allow source_type target_type:target_class permission(s);
Это работает, потому что политика была написана со знанием всех типов. Однако если политика поставщика и политика платформы используют определенные типы, а метка определенного объекта изменяется только в одной из этих политик, другая может содержать политику, к которой ранее полагался доступ или потерян доступ. Например:
File_contexts: /sys/A u:object_r:sysfs:s0 Platform: allow p_domain sysfs:class perm; Vendor: allow v_domain sysfs:class perm;
Можно изменить на:
File_contexts: /sys/A u:object_r:sysfs_A:s0
Хотя политика поставщика останется прежней, v_domain
потеряет доступ из-за отсутствия политики для нового типа sysfs_A
.
Определив политику в терминах атрибутов, мы можем придать базовому объекту тип, который имеет атрибут, соответствующий политике как для кода платформы, так и для кода поставщика. Это можно сделать для всех типов, чтобы эффективно создать политику атрибутов, в которой конкретные типы никогда не используются. На практике это требуется только для тех частей политики, которые пересекаются между платформой и поставщиком, которые определяются и предоставляются как общедоступная политика платформы , которая создается как часть политики поставщика.
Определение общедоступной политики как версионных атрибутов удовлетворяет двум целям совместимости политик:
- Убедитесь, что код поставщика продолжает работать после обновления платформы. Достигается путем добавления атрибутов к конкретным типам объектов, соответствующих тем, на которые опирается код поставщика, с сохранением доступа.
- Возможность отказаться от политики. Достигается за счет четкого разграничения наборов политик по атрибутам, которые можно удалить, как только версия, которой они соответствуют, перестанет поддерживаться. Разработка может продолжаться на платформе, зная, что старая политика все еще присутствует в политике поставщика и будет автоматически удалена при обновлении.
Возможность записи политики
Чтобы не требовать знания конкретных изменений версий для разработки политики, Android 8.0 включает сопоставление между типами общедоступных политик платформы и их атрибутами. Тип foo
сопоставляется с атрибутом foo_v N
, где N
— целевая версия. vN
соответствует переменной сборки PLATFORM_SEPOLICY_VERSION
и имеет вид MM.NN
, где MM
соответствует номеру SDK платформы, а NN
— версия, специфичная для платформы sepolicy.
Атрибуты в публичной политике не версионируются, а существуют как API, на котором может строиться политика платформы и поставщика, чтобы поддерживать стабильность интерфейса между двумя разделами. Разработчики политики как платформы, так и поставщика могут продолжать писать политику в том виде, в котором она написана сегодня.
Публичная политика платформы экспортирована как allow source_foo target_bar: class perm ;
включено в политику поставщика. Во время компиляции (которая включает соответствующую версию) она преобразуется в политику, которая будет передана в часть устройства производителя (показана в преобразованном Common Intermediate Language (CIL)):
(allow source_foo_vN target_bar_vN (class (perm)))
Поскольку политика поставщика никогда не опережает платформу, она не должна касаться предыдущих версий. Однако политика платформы должна знать, насколько давно существует политика поставщика, включать атрибуты в ее типы и устанавливать политику, соответствующую версионным атрибутам.
Различия в политике
Автоматическое создание атрибутов путем добавления _v N
в конец каждого типа ничего не дает без сопоставления атрибутов с типами в разных версиях. Android поддерживает сопоставление версий атрибутов и сопоставление типов с этими атрибутами. Это делается в вышеупомянутых файлах сопоставления с помощью таких операторов, как (CIL):
(typeattributeset foo_vN (foo))
Обновления платформы
В следующем разделе подробно описаны сценарии обновления платформы.
Те же типы
Этот сценарий возникает, когда объект не меняет метки в версиях политики. Это одинаково для исходных и целевых типов, и это можно увидеть с помощью /dev/binder
, который во всех выпусках помечен binder_device
. В трансформированной политике это представлено как:
binder_device_v1 … binder_device_vN
При обновлении с v1
→ v2
политика платформы должна содержать:
type binder_device; -> (type binder_device) (in CIL)
В файле сопоставления v1 (CIL):
(typeattributeset binder_device_v1 (binder_device))
В файле сопоставления v2 (CIL):
(typeattributeset binder_device_v2 (binder_device))
В политике поставщика v1 (CIL):
(typeattribute binder_device_v1) (allow binder_device_v1 …)
В политике поставщика v2 (CIL):
(typeattribute binder_device_v2) (allow binder_device_v2 …)
Новые типы
Этот сценарий возникает, когда платформа добавляет новый тип, что может произойти при добавлении новых функций или во время ужесточения политики.
- Новая функция. Когда тип помечает объект, который ранее не существовал (например, новый процесс обслуживания), код поставщика ранее не взаимодействовал с ним напрямую, поэтому соответствующей политики не существует. Новый атрибут, соответствующий типу, не имеет атрибута в предыдущей версии, поэтому ему не потребуется запись в файле сопоставления, предназначенная для этой версии.
- Ужесточение политики. Если тип представляет собой ужесточение политики, новый атрибут типа должен быть связан с цепочкой атрибутов, соответствующей предыдущему (аналогично предыдущему примеру, где
/sys/A
меняется сsysfs
наsysfs_A
). Код поставщика опирается на правило, разрешающее доступ кsysfs
, и должен включать это правило в качестве атрибута нового типа.
При обновлении с v1
→ v2
политика платформы должна содержать:
type sysfs_A; -> (type sysfs_A) (in CIL) type sysfs; (type sysfs) (in CIL)
В файле сопоставления v1 (CIL):
(typeattributeset sysfs_v1 (sysfs sysfs_A))
В файле сопоставления v2 (CIL):
(typeattributeset sysfs_v2 (sysfs)) (typeattributeset sysfs_A_v2 (sysfs_A))
В политике поставщика v1 (CIL):
(typeattribute sysfs_v1) (allow … sysfs_v1 …)
В политике поставщика v2 (CIL):
(typeattribute sysfs_A_v2) (allow … sysfs_A_v2 …) (typeattribute sysfs_v2) (allow … sysfs_v2 …)
Удаленные типы
Этот (редкий) сценарий возникает при удалении типа, что может произойти, когда базовый объект:
- Остается, но получает другую метку.
- Убирается платформой.
При ослаблении политики тип удаляется, а объекту, помеченному этим типом, присваивается другая, уже существующая метка. Это представляет собой объединение сопоставлений атрибутов: код поставщика по-прежнему должен иметь возможность доступа к базовому объекту по атрибуту, которым он раньше обладал, но остальная часть системы теперь должна иметь возможность доступа к нему с помощью нового атрибута.
Если атрибут, на который он был переключен, является новым, то изменение метки происходит так же, как и в случае с новым типом, за исключением того, что при использовании существующей метки добавление нового типа старого атрибута приведет к тому, что другие объекты также будут помечены этим типом. чтобы стать новым доступным. По сути, это то, что делает платформа, и это считается приемлемым компромиссом для обеспечения совместимости.
(typeattribute sysfs_v1) (allow … sysfs_v1 …)
Пример версии 1: Свертывание типов (удаление sysfs_A)
При обновлении с v1
→ v2
политика платформы должна содержать:
type sysfs; (type sysfs) (in CIL)
В файле сопоставления v1 (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))
В файле сопоставления v2 (CIL):
(typeattributeset sysfs_v2 (sysfs))
В политике поставщика v1 (CIL):
(typeattribute sysfs_A_v1) (allow … sysfs_A_v1 …) (typeattribute sysfs_v1) (allow … sysfs_v1 …)
В политике поставщика v2 (CIL):
(typeattribute sysfs_v2) (allow … sysfs_v2 …)
Пример версии 2: полное удаление (тип foo)
При обновлении с v1
→ v2
политика платформы должна содержать:
# nothing - we got rid of the type
В файле сопоставления v1 (CIL):
(type foo) #needed in case vendors used the foo label on objects (typeattributeset foo_v1 (foo))
В файле сопоставления v2 (CIL):
# nothing - get rid of it
В политике поставщика v1 (CIL):
(typeattribute foo_v1) (allow foo …) (typeattribute sysfs_v1) (allow sysfs_v1 …)
В политике поставщика v2 (CIL):
(typeattribute sysfs_v2) (allow sysfs_v2 …)
Новый класс/разрешения
Этот сценарий возникает, когда при обновлении платформы появляются новые компоненты политики, которых не было в предыдущих версиях. Например, когда Android добавил диспетчер объектов servicemanager
, который создавал разрешения на добавление, поиск и список, демонам поставщиков, желающим зарегистрироваться в servicemanager
требовались разрешения, которых не было. В Android 8.0 только политика платформы может добавлять новые классы и разрешения.
Чтобы разрешить всем доменам, которые могли быть созданы или расширены политикой поставщика, беспрепятственно использовать новый класс, политика платформы должна включать правило, подобное:
allow {domain -coredomain} *:new_class perm;
Для этого может даже потребоваться политика, разрешающая доступ ко всем типам интерфейсов (публичная политика), чтобы быть уверенным, что образ поставщика получит доступ. Если это приведет к неприемлемой политике безопасности (как это может произойти с изменениями в диспетчере служб), потенциально может потребоваться принудительное обновление поставщика.
Удален класс/разрешения
Этот сценарий возникает при удалении диспетчера объектов (например, диспетчера объектов ZygoteConnection
) и не должен вызывать проблем. Класс и разрешения диспетчера объектов могут оставаться определенными в политике до тех пор, пока версия поставщика не перестанет их использовать. Это делается путем добавления определений в соответствующий файл сопоставления.
Настройка поставщика для новых/измененных типов
Новые типы поставщиков лежат в основе разработки политики поставщиков, поскольку они необходимы для описания новых процессов, двоичных файлов, устройств, подсистем и хранимых данных. Таким образом, крайне важно разрешить создание типов, определяемых поставщиком.
Поскольку политика поставщика всегда является самой старой на устройстве, нет необходимости автоматически преобразовывать все типы поставщиков в атрибуты политики. Платформа не полагается ни на что, указанное в политике поставщика, поскольку платформа ничего об этом не знает; однако платформа предоставит атрибуты и общедоступные типы, которые она использует для взаимодействия с объектами, помеченными этими типами (например, domain
, sysfs_type
и т. д.). Чтобы платформа продолжала правильно взаимодействовать с этими объектами, атрибуты и типы должны применяться соответствующим образом, а в настраиваемые домены (например, init
) может потребоваться добавить определенные правила.
Изменения атрибутов для Android 9
Устройства, обновляющиеся до Android 9, могут использовать следующие атрибуты, но устройства, запускаемые с Android 9, не должны.
Атрибуты нарушителя
Android 9 включает следующие атрибуты, связанные с доменом:
-
data_between_core_and_vendor_violators
. Атрибут для всех доменов, которые нарушают требование о запрете совместного использования файлов по пути междуvendor
иcoredomains
. Процессы платформы и поставщика не должны использовать для связи файлы на диске (нестабильный ABI). Рекомендация:- Код поставщика должен использовать
/data/vendor
. - Система не должна использовать
/data/vendor
.
- Код поставщика должен использовать
-
system_executes_vendor_violators
. Атрибут для всех системных доменов (кроме доменовinit
иshell domains
), которые нарушают требование не выполнять двоичные файлы поставщика. Исполнение двоичных файлов поставщиков имеет нестабильный API. Платформа не должна напрямую выполнять двоичные файлы поставщиков. Рекомендация:- Такие зависимости платформы от двоичных файлов поставщиков должны лежать в основе HIDL HAL.
ИЛИ
-
coredomains
, которым требуется доступ к двоичным файлам поставщика, следует переместить в раздел поставщика и, таким образом, перестать бытьcoredomain
.
- Такие зависимости платформы от двоичных файлов поставщиков должны лежать в основе HIDL HAL.
Ненадежные атрибуты
Ненадежные приложения, содержащие произвольный код, не должны иметь доступа к службам HwBinder, за исключением тех, которые считаются достаточно безопасными для доступа из таких приложений (см. безопасные службы ниже). Двумя основными причинами этого являются:
- Серверы HwBinder не выполняют аутентификацию клиента, поскольку HIDL в настоящее время не раскрывает информацию UID вызывающего абонента. Даже если HIDL действительно предоставляет такие данные, многие службы HwBinder либо работают на уровне ниже уровня приложений (например, HAL), либо не должны полагаться на идентификатор приложения для авторизации. Таким образом, в целях безопасности по умолчанию предполагается, что каждая служба HwBinder рассматривает всех своих клиентов как одинаково уполномоченных выполнять операции, предлагаемые службой.
- Серверы HAL (подмножество сервисов HwBinder) содержат код с более высоким уровнем проблем безопасности, чем
system/core
компоненты, и имеют доступ к нижним уровням стека (вплоть до аппаратного обеспечения), что увеличивает возможности обхода модели безопасности Android. .
Безопасные услуги
Безопасные услуги включают в себя:
-
same_process_hwservice
. Эти службы (по определению) выполняются в процессе клиента и, следовательно, имеют тот же доступ, что и клиентский домен, в котором выполняется процесс. -
coredomain_hwservice
. Эти услуги не несут рисков, связанных с причиной №2. -
hal_configstore_ISurfaceFlingerConfigs
. Эта услуга специально разработана для использования любым доменом. -
hal_graphics_allocator_hwservice
. Эти операции также предлагает службаsurfaceflinger
Binder, к которой приложениям разрешен доступ. -
hal_omx_hwservice
. Это версия HwBinder службыmediacodec
Binder, к которой приложениям разрешен доступ. -
hal_codec2_hwservice
. Это более новая версияhal_omx_hwservice
.
Полезные атрибуты
Все hwservices
не считающиеся безопасными, имеют атрибут untrusted_app_visible_hwservice
. Соответствующие серверы HAL имеют атрибут untrusted_app_visible_halserver
. Устройства, запускаемые с Android 9, НЕ ДОЛЖНЫ использовать ни один из атрибутов untrusted
.
Рекомендация:
- Вместо этого ненадежные приложения должны обращаться к системной службе, которая взаимодействует с поставщиком HIDL HAL. Например, приложения могут обращаться к
binderservicedomain
, а затемmediaserver
(который являетсяbinderservicedomain
), в свою очередь, обращается кhal_graphics_allocator
.ИЛИ
- Приложения, которым требуется прямой доступ к HAL
vendor
должны иметь собственный домен sepolicy, определенный поставщиком.
Тесты атрибутов файлов
Android 9 включает тесты времени сборки , которые гарантируют, что все файлы в определенных местах имеют соответствующие атрибуты (например, все файлы в sysfs
имеют обязательный атрибут sysfs_type
).
Платформа-публичная политика
Публичная политика платформы — это основа соответствия модели архитектуры Android 8.0 без простого сохранения объединения политик платформы из версий 1 и 2. Поставщики подвергаются воздействию подмножества политики платформы, которое содержит используемые типы и атрибуты, а также правила для этих типов и атрибутов, которые затем становятся частью политики поставщика (то есть, vendor_sepolicy.cil
).
Типы и правила автоматически преобразуются в политике, созданной поставщиком, в attribute_v N
, так что все типы, предоставляемые платформой, являются версионными атрибутами (однако атрибуты не версионируются). Платформа отвечает за сопоставление конкретных типов, которые она предоставляет, с соответствующими атрибутами, чтобы гарантировать, что политика поставщика продолжает функционировать и что правила, предусмотренные для конкретной версии, включены. Сочетание общедоступной политики платформы и политики поставщиков соответствует цели модели архитектуры Android 8.0, заключающейся в обеспечении независимых сборок платформ и поставщиков.
Сопоставление с цепочками атрибутов
При использовании атрибутов для сопоставления с версиями политики тип сопоставляется с атрибутом или несколькими атрибутами, обеспечивая доступность объектов, помеченных этим типом, через атрибуты, соответствующие их предыдущим типам.
Поддержание цели скрыть информацию о версии от автора политики означает автоматическое создание версионных атрибутов и присвоение им соответствующих типов. В обычном случае статических типов это просто: type_foo
сопоставляется с type_foo_v1
.
Для изменения метки объекта, например sysfs
→ sysfs_A
или mediaserver
→ audioserver
, создание этого сопоставления является нетривиальной задачей (и описано в примерах выше). Специалисты по сопровождению политики платформы должны определить, как создавать сопоставления в точках перехода для объектов, что требует понимания взаимосвязи между объектами и назначенными им метками и определения того, когда это происходит. Для обеспечения обратной совместимости этой сложностью необходимо управлять на стороне платформы, которая является единственным разделом, который может быть обновлен.
Обновление версии
Для простоты платформа Android выпускает версию sepolicy при вырезании новой ветки выпуска. Как описано выше, номер версии содержится в PLATFORM_SEPOLICY_VERSION
и имеет форму MM.nn
, где MM
соответствует значению SDK, а nn
— это частное значение, хранящееся в /platform/system/sepolicy.
Например, 19.0
для Kitkat, 21.0
для Lollipop, 22.0
для Lollipop-MR1, 23.0
для Marshmallow, 24.0
для Nougat, 25.0
для Nougat-MR1, 26.0
для Oreo, 27.0
для Oreo-MR1 и 28.0
для Android 9. Uprevs не являются всегда целые числа. Например, если изменение версии MR требует несовместимого изменения в system/sepolicy/public
, но не изменения API, то эта версия sepolicy может быть: vN.1
. Версия, присутствующая в ветке разработки, — это никогда не используемая в поставляемых устройствах 10000.0
.
Android может отказаться от самой старой версии при обновлении. Чтобы узнать, когда следует прекратить поддержку той или иной версии, Android может собирать данные о количестве устройств с политиками поставщика, на которых установлена эта версия Android и которые все еще получают основные обновления платформы. Если число меньше определенного порога, эта версия считается устаревшей.
Влияние нескольких атрибутов на производительность
Как описано в https://github.com/SELinuxProject/cil/issues/9 , большое количество атрибутов, назначенных типу, приводит к проблемам с производительностью в случае промаха кэша политики.
Было подтверждено, что это проблема в Android, поэтому в Android 8.0 были внесены изменения для удаления атрибутов, добавленных в политику компилятором политики, а также для удаления неиспользуемых атрибутов. Эти изменения устранили снижение производительности.
общедоступная политика system_ext и продукта
Начиная с Android 11, разделам system_ext
и product
разрешено экспортировать назначенные им общедоступные типы в раздел поставщика. Подобно общедоступной политике платформы, поставщик использует типы и правила, автоматически преобразуемые в версионные атрибуты, например, из type
в type_ N
, где N
— версия платформы, на которой построен раздел поставщика.
Если разделы system_ext
и product
основаны на одной и той же версии платформы N
, система сборки генерирует файлы базового сопоставления с system_ext/etc/selinux/mapping/ N .cil
и product/etc/selinux/mapping/ N .cil
, которые содержат идентификаторы. сопоставления type
с type_ N
. Поставщик может получить доступ к type
с помощью версионного атрибута type_ N
В случае, если обновляются только разделы system_ext
и product
, скажем, N
до N+1
(или более поздней версии), а поставщик остается на уровне N
, поставщик может потерять доступ к типам разделов system_ext
и product
. Чтобы предотвратить поломку, разделы system_ext
и product
должны обеспечивать сопоставление файлов конкретных типов с атрибутами type_ N
Каждый партнер несет ответственность за поддержание файлов сопоставления, если он собирается поддерживать N
поставщиков с N+1
(или более поздними версиями) system_ext
и разделами product
.
Для этого партнеры должны:
- Скопируйте сгенерированные файлы базового сопоставления из
N
разделовsystem_ext
иproduct
в их исходное дерево. - При необходимости измените файлы сопоставления.
- Установите файлы сопоставления в разделы
system_ext
иproduct
N+1
(или более поздней версии).
Например, предположим, что N
system_ext
имеет один общедоступный тип с именем foo_type
. Тогда system_ext/etc/selinux/mapping/ N .cil
в разделе N
system_ext
будет выглядеть так:
(typeattributeset foo_type_N (foo_type)) (expandtypeattribute foo_type_N true) (typeattribute foo_type_N)
Если bar_type
добавлен в N+1
system_ext и если bar_type
должен быть сопоставлен с foo_type
для поставщика N
, N .cil
можно обновить из
(typeattributeset foo_type_N (foo_type))
к
(typeattributeset foo_type_N (foo_type bar_type))
а затем установлен в раздел N+1
system_ext. Поставщик N
может продолжать доступ к foo_type
и bar_type
N+1
system_ext.
Маркировка контекстов SELinux
Чтобы обеспечить различие между политикой безопасности платформы и поставщика, система по-разному создает файлы контекста SELinux, чтобы хранить их отдельно.
Контексты файлов
В Android 8.0 для file_contexts
внесены следующие изменения:
- Чтобы избежать дополнительных затрат на компиляцию на устройстве во время загрузки,
file_contexts
перестает существовать в двоичной форме. Вместо этого они представляют собой читаемые текстовые файлы с регулярными выражениями, такие как{property, service}_contexts
(как они были до версии 7.0). -
file_contexts
разделен между двумя файлами:-
plat_file_contexts
-
file_context
платформы Android, который не имеет меток, специфичных для устройства, за исключением маркировки частей раздела/vendor
, которые должны быть точно помечены, чтобы обеспечить правильное функционирование файлов sepolicy. - Должен находиться в
system
разделе/system/etc/selinux/plat_file_contexts
на устройстве и загружаться с помощьюinit
в начале вместе сfile_context
поставщика.
-
-
vendor_file_contexts
-
file_context
зависящий от устройства, создается путем объединенияfile_contexts
найденных в каталогах, на которые указываетBOARD_SEPOLICY_DIRS
, в файлахBoardconfig.mk
устройства. - Должен быть установлен в
/vendor/etc/selinux/vendor_file_contexts
в разделеvendor
и загружен с помощьюinit
в начале вместе сfile_context
платформы.
-
-
Контексты свойств
В Android 8.0 property_contexts
разделен между двумя файлами:
-
plat_property_contexts
-
property_context
платформы Android, не имеющий меток, специфичных для устройства. - Должен находиться в
system
разделе/system/etc/selinux/plat_property_contexts
и загружаться с помощьюinit
в начале вместе с файломproperty_contexts
поставщика.
-
-
vendor_property_contexts
-
property_context
, специфичный для устройства, создается путем объединенияproperty_contexts
найденных в каталогах, на которые указываетBOARD_SEPOLICY_DIRS
в файлахBoardconfig.mk
устройства. - Должен находиться в разделе
vendor
по адресу/vendor/etc/selinux/vendor_property_contexts
и загружаться с помощьюinit
в начале вместе сproperty_context
платформы.
-
Контексты обслуживания
В Android 8.0 файл service_contexts
разделен между следующими файлами:
-
plat_service_contexts
-
service_context
для платформы Android дляservicemanager
.service_context
не имеет меток, специфичных для устройства. - Должен находиться в
system
разделе/system/etc/selinux/plat_service_contexts
и загружатьсяservicemanager
в начале вместе с поставщикомservice_contexts
.
-
-
vendor_service_contexts
-
service_context
для конкретного устройства, созданный путем объединенияservice_contexts
, найденных в каталогах, на которые указываетBOARD_SEPOLICY_DIRS
, в файлахBoardconfig.mk
устройства. - Должен находиться в разделе
vendor
по адресу/vendor/etc/selinux/vendor_service_contexts
и загружатьсяservicemanager
в начале вместе с платформойservice_contexts
. - Несмотря на то, что
servicemanager
ищет этот файл во время загрузки, для полностью совместимого устройстваTREBLE
vendor_service_contexts
НЕ ДОЛЖЕН существовать. Это связано с тем, что все взаимодействие междуvendor
иsystem
процессами ДОЛЖНО проходить черезhwservicemanager
/hwbinder
.
-
-
plat_hwservice_contexts
- Платформа Android
hwservice_context
дляhwservicemanager
, не имеющая меток для конкретного устройства. - Должен находиться в
system
разделе/system/etc/selinux/plat_hwservice_contexts
и загружатьсяhwservicemanager
в начале вместе сvendor_hwservice_contexts
.
- Платформа Android
-
vendor_hwservice_contexts
-
hwservice_context
для конкретного устройства, созданный путем объединенияhwservice_contexts
, найденных в каталогах, на которые указываетBOARD_SEPOLICY_DIRS
в файлахBoardconfig.mk
устройства. - Должен находиться в разделе
vendor
по адресу/vendor/etc/selinux/vendor_hwservice_contexts
и загружатьсяhwservicemanager
в начале вместе сplat_service_contexts
.
-
-
vndservice_contexts
-
service_context
для конкретного устройства дляvndservicemanager
созданный путем объединенияvndservice_contexts
, найденных в каталогах, на которые указываетBOARD_SEPOLICY_DIRS
вBoardconfig.mk
устройства. - Этот файл должен находиться в разделе
vendor
по адресу/vendor/etc/selinux/vndservice_contexts
и загружаться с помощьюvndservicemanager
при запуске.
-
Контексты Seaapp
В Android 8.0 seapp_contexts
разделен на два файла:
-
plat_seapp_contexts
- Платформа Android
seapp_context
, не имеющая изменений для конкретного устройства. - Должен находиться в
system
разделе/system/etc/selinux/plat_seapp_contexts.
- Платформа Android
-
vendor_seapp_contexts
- Расширение платформы
seapp_context
, специфичное для устройства, созданное путем объединенияseapp_contexts
, найденного в каталогах, на которые указываетBOARD_SEPOLICY_DIRS
в файлахBoardconfig.mk
устройства. - Должен проживать в разделе
vendor
AT/vendor/etc/selinux/vendor_seapp_contexts
.
- Расширение платформы
MAC разрешения
В Android 8.0 mac_permissions.xml
разделен между двумя файлами:
- Платформа
mac_permissions.xml
- Android Platform
mac_permissions.xml
, которая не имеет специфических для устройства изменений. - Должен проживать в
system
разделе AT/system/etc/selinux/.
- Android Platform
- Неплатформенный
mac_permissions.xml
- Расширение для конкретного устройства на платформу
mac_permissions.xml
построенное изmac_permissions.xml
, найденное в каталогах, указанныхBOARD_SEPOLICY_DIRS
в файлахBoardconfig.mk
. - Должен проживать в разделе
vendor
AT/vendor/etc/selinux/.
- Расширение для конкретного устройства на платформу