Совместимость политики

В этой статье описывается, как Android решает проблемы совместимости политик с OTA-версиями платформ, где новые настройки SELinux платформы могут отличаться от старых настроек SELinux поставщика.

Проектирование политики SELinux на основе Treble учитывает бинарное различие между политикой платформы и поставщика ; схема становится более сложной, если разделы поставщика генерируют зависимости, такие как platform < vendor < oem .

В Android 8.0 и выше глобальная политика SELinux разделена на частные и публичные компоненты. Публичные компоненты состоят из политики и связанной с ней инфраструктуры, которые гарантированно доступны для версии платформы. Эта политика будет предоставлена ​​разработчикам политики поставщика, чтобы поставщики могли создать файл политики поставщика, который в сочетании с политикой, предоставленной платформой, приводит к полностью функциональной политике для устройства.

  • Для управления версиями экспортированная политика платформы-public будет записана в виде атрибутов .
  • Для удобства написания политики экспортированные типы будут преобразованы в версионные атрибуты в рамках процесса построения политики. Публичные типы также могут использоваться напрямую в решениях по маркировке, предоставляемых файлами контекстов поставщиков.

Android поддерживает сопоставление между экспортированными конкретными типами в политике платформы и соответствующими версионными атрибутами для каждой версии платформы. Это гарантирует, что когда объекты помечены типом, это не нарушает поведение, гарантированное политикой platform-public в предыдущей версии. Это сопоставление поддерживается путем поддержания актуальности файла сопоставления для каждой версии платформы , который сохраняет информацию о членстве атрибутов для каждого типа, экспортированного в политике public.

Право собственности на объект и маркировка

При настройке политики в 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 только для фреймворка может оказаться невозможным.

Поставщик (/поставщик)

Политика SELinux AOSP уже маркирует части раздела vendor , с которыми взаимодействует платформа, что позволяет писать правила SELinux для процессов платформы, чтобы иметь возможность общаться и/или получать доступ к частям раздела vendor . Примеры:

/vendor Метка, предоставленная платформой Процессы платформы в зависимости от лейбла
/vendor(/. * )? vendor_file Все клиенты HAL в фреймворке, 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 passthrough.
  • Все новые exec_types добавленные в раздел vendor через SEPolicy поставщика, должны иметь атрибут vendor_file_type . Это обеспечивается через neverallows.
  • Чтобы избежать конфликтов с будущими обновлениями платформы/фреймворка, не маркируйте файлы, отличные от exec_types в разделе vendor .
  • Все зависимости библиотек для тех же процессов HAL, которые идентифицированы AOSP, должны быть помечены как same_process_hal_file.

Прокфс (/proc)

Файлы в /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 .

Sysfs (/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 ).

Rootfs (/)

Файлы в / могут быть помечены в file_contexts . В Android 7.0 и платформа, и поставщик помечают файлы здесь.

Рекомендация: Только система может маркировать файлы в / .

Данные (/данные)

Данные маркируются с помощью комбинации file_contexts и seapp_contexts .

Рекомендация: Запретить маркировку поставщиков за пределами /data/vendor . Только платформа может маркировать другие части /data .

Версия меток Genfs

Начиная с уровня API поставщика 202504, новые метки 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.

Атрибуты совместимости

Политика 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 включает сопоставление между типами политики platform-public и их атрибутами. Тип foo сопоставляется с атрибутом foo_v N , где N — целевая версия. vN соответствует переменной сборки PLATFORM_SEPOLICY_VERSION и имеет форму MM.NN , где MM соответствует номеру SDK платформы, а NN — специфической для платформы версии sepolicy.

Атрибуты в публичной политике не версионируются, а существуют как API, на котором может строиться политика платформы и поставщика, чтобы поддерживать стабильный интерфейс между двумя разделами. Авторы политики платформы и поставщика могут продолжать писать политику так, как она написана сегодня.

Platform-public политика экспортируется как 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

При обновлении с v1v2 политика платформы должна содержать:

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 , и должен включить это правило в качестве атрибута нового типа.

При обновлении с v1v2 политика платформы должна содержать:

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)

При обновлении с v1v2 политика платформы должна содержать:

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)

При обновлении с v1v2 политика платформы должна содержать:

# 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;

Это может даже потребовать политики, разрешающей доступ для всех типов интерфейсов (публичная политика), чтобы гарантировать, что образ поставщика получит доступ. Если это приведет к неприемлемой политике безопасности (как это могло произойти с изменениями в servicemanager), обновление поставщика может быть потенциально вынужденным.

Удалён класс/разрешения

Этот сценарий возникает, когда удаляется менеджер объектов (например, менеджер объектов 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 .

Ненадежные атрибуты

Недоверенные приложения, размещающие произвольный код, не должны иметь доступа к службам HwBinder, за исключением тех, которые считаются достаточно безопасными для доступа из таких приложений (см. безопасные службы ниже). Две основные причины для этого:

  1. Серверы HwBinder не выполняют аутентификацию клиента, поскольку HIDL в настоящее время не раскрывает информацию об UID вызывающего абонента. Даже если бы HIDL раскрывал такие данные, многие службы HwBinder либо работают на уровне ниже уровня приложений (например, HAL), либо не должны полагаться на идентификацию приложения для авторизации. Таким образом, для обеспечения безопасности по умолчанию предполагается, что каждая служба HwBinder рассматривает всех своих клиентов как одинаково уполномоченных на выполнение операций, предлагаемых службой.
  2. Серверы HAL (подмножество служб HwBinder) содержат код с более высокой частотой возникновения проблем безопасности, чем system/core компоненты, и имеют доступ к нижним уровням стека (вплоть до аппаратного обеспечения), что увеличивает возможности обхода модели безопасности Android.

Безопасные услуги

Безопасные услуги включают в себя:

  • same_process_hwservice . Эти службы (по определению) запускаются в процессе клиента и, таким образом, имеют тот же доступ, что и домен клиента, в котором запускается процесс.
  • coredomain_hwservice . Эти сервисы не представляют рисков, связанных с причиной №2.
  • hal_configstore_ISurfaceFlingerConfigs . Эта служба специально разработана для использования любым доменом.
  • hal_graphics_allocator_hwservice . Эти операции также предлагаются службой Binder surfaceflinger , к которой приложениям разрешен доступ.
  • 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 ).

Платформа-государственная политика

Политика platform-public является ядром соответствия архитектурной модели Android 8.0 без простого поддержания объединения политик платформы из v1 и v2. Поставщики подвергаются воздействию подмножества политики платформы, которое содержит используемые типы и атрибуты, а также правила для этих типов и атрибутов, которые затем становятся частью политики поставщика (то есть vendor_sepolicy.cil ).

Типы и правила автоматически транслируются в политике, сгенерированной поставщиком, в attribute_v N таким образом, что все типы, предоставляемые платформой, являются версионированными атрибутами (однако атрибуты не версионируются). Платформа отвечает за сопоставление конкретных типов, которые она предоставляет, с соответствующими атрибутами, чтобы гарантировать, что политика поставщика продолжает функционировать и что правила, предоставляемые для конкретной версии, включены. Сочетание политики платформы-общедоступной и политики поставщика удовлетворяет цели модели архитектуры Android 8.0, которая заключается в разрешении независимых сборок платформы и поставщика.

Сопоставление с цепочками атрибутов

При использовании атрибутов для сопоставления с версиями политики тип сопоставляется с атрибутом или несколькими атрибутами, гарантируя, что объекты, помеченные этим типом, доступны через атрибуты, соответствующие их предыдущим типам.

Поддержание цели скрыть информацию о версии от автора политики означает автоматическую генерацию версионных атрибутов и назначение их соответствующим типам. В общем случае статических типов это просто: type_foo отображается на type_foo_v1 .

Для изменения метки объекта, например, sysfssysfs_A или mediaserveraudioserver , создание этого сопоставления нетривиально (и описано в примерах выше). Сопровождающие политики платформы должны определить, как создать сопоставление в точках перехода для объектов, что требует понимания взаимосвязи между объектами и назначенными им метками и определения того, когда это происходит. Для обратной совместимости эта сложность должна управляться на стороне платформы, которая является единственным разделом, который может быть обновлен.

Версия uprevs

Для простоты платформа 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. Uprev не всегда являются целыми числами. Например, если повышение версии 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 с разделами system_ext и product N+1 (или позже).

Для этого от партнеров ожидается:

  1. Скопируйте сгенерированные файлы базового сопоставления из N разделов system_ext и product в их исходное дерево.
  2. При необходимости внесите изменения в файлы сопоставления.
  3. Установите файлы сопоставления на разделы 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
    • Специфичный для платформы Android service_context для 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 .
  • 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.
  • 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/.
  • Неплатформенный mac_permissions.xml
    • Расширение для конкретного устройства на платформу mac_permissions.xml , построенное из mac_permissions.xml Boardconfig.mk найденное в каталогах, указанных BOARD_SEPOLICY_DIRS в файлах устройства.
    • Должен проживать в разделе vendor AT /vendor/etc/selinux/.