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

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

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

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

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

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

Владение объектами и маркировка

При настройке политики в Android 8.0 и более поздних версиях необходимо четко определить право собственности для каждого объекта, чтобы разделить политику платформы и поставщика. Например, если поставщик помечает /dev/foo , а платформа затем помечает /dev/foo в последующем OTA, поведение будет неопределенным. Для SELinux это проявляется как коллизия меток. Узел устройства может иметь только одну метку, которая разрешается в зависимости от того, какая метка была применена последней. Как результат:

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

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

В дополнение к конфликтам меток также могут конфликтовать имена типов/атрибутов SELinux. Конфликт имени типа/атрибута всегда приводит к ошибке компилятора политики.

Пространство имен типа/атрибута

SELinux не допускает множественных объявлений одного и того же типа/атрибута. Политика с повторяющимися объявлениями не будет компилироваться. Чтобы избежать конфликтов имен типов и атрибутов, все объявления поставщиков должны иметь пространство имен, начинающееся с np_ .

type foo, domain; → type np_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.* (очевидное свойство, связанное с аппаратным обеспечением).

Все сервисы поставщиков в файлах инициализации rc должны иметь vendor. для служб в файлах init rc несистемных разделов. Аналогичные правила применяются к меткам SELinux для свойств поставщика ( vendor_ для свойств поставщика).

Владение файлом

Предотвращение конфликтов для файлов является сложной задачей, поскольку политика платформы и поставщика обычно предоставляет метки для всех файловых систем. В отличие от именования типов, пространство имен файлов нецелесообразно, поскольку многие из них создаются ядром. Чтобы предотвратить эти коллизии, следуйте инструкциям по именованию файловых систем в этом разделе. Для Android 8.0 это рекомендации без технического контроля. В будущем эти рекомендации будут применяться с помощью Vendor Test Suite (VTS).

Система (/система)

Только образ системы должен предоставлять метки для компонентов /system через file_contexts , service_contexts и т. д. Если метки для компонентов /system добавлены в политику /vendor , обновление OTA только для платформы может оказаться невозможным.

Продавец (/продавец)

Политика 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 и т. д.

В результате необходимо соблюдать определенные правила (обеспечиваемые через neverallows ) при маркировке дополнительных файлов в разделе vendor :

  • vendor_file должен быть меткой по умолчанию для всех файлов в разделе vendor . Политика платформы требует этого для доступа к сквозным реализациям HAL.
  • Все новые 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 .

Трассировки (/sys/kernel/debug/tracing)

Tracefs могут быть помечены как в file_contexts так и в genfscon . В Android 7.0 только платформа tracefs .

Рекомендация: только платформа может помечать tracefs .

Системные файлы (/sys)

Файлы в /sys могут быть помечены как с помощью file_contexts так и с помощью genfscon . В Android 7.0 и платформа, и поставщик используют file_contexts и 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 .

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

Политика 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 , который помечен как 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;

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

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

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

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

Версии обновлений

Для простоты платформа 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. всегда целые числа. Например, если переход 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.

Для этого партнеры должны:

  1. Скопируйте сгенерированные файлы базового сопоставления из N разделов system_ext и продукта в их исходное дерево.
  2. Внесите необходимые изменения в файлы сопоставления.
  3. Установите файлы сопоставления в N+1 (или более поздние) разделы system_ext и product.

Например, предположим, что 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))

а затем установлен в раздел system_ext N+1 . Поставщик 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
    • Платформа Android property_context , не имеющая ярлыков для конкретных устройств.
    • Должен находиться в 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 .
  • 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 по адресу /vendor/etc/selinux/vendor_seapp_contexts .

MAC-разрешения

В Android 8.0 mac_permissions.xml разделен на два файла:

  • Платформа mac_permissions.xml
    • Платформа Android mac_permissions.xml , в котором нет изменений для конкретных устройств.
    • Должен находиться в system разделе /system/etc/selinux/.
  • mac_permissions.xml
    • Зависимое от устройства расширение для платформы mac_permissions.xml , созданное из mac_permissions.xml найденного в каталогах, на которые указывает BOARD_SEPOLICY_DIRS в файлах Boardconfig.mk устройства.
    • Должен находиться в разделе vendor по адресу /vendor/etc/selinux/.