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

В этой статье описывается, как 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 не допускает несколько объявлений одного и того же типа/атрибута. Политика с повторяющимися объявлениями не будет скомпилирована. Чтобы избежать конфликтов имен типов и атрибутов, все объявления поставщиков должны начинаться с 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.* (очевидное свойство, связанное с оборудованием).

Все службы поставщика в файлах 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 и платформа, и поставщик используют 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_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 , которым необходим доступ к двоичным файлам поставщика, следует переместить в раздел поставщика и, таким образом, перестать быть 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. 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 и продукта, скажем, N до N+1 (или более поздней версии), а поставщик остается на уровне N , поставщик может потерять доступ к типам разделов system_ext и продукта. Чтобы предотвратить поломку, разделы system_ext и product должны обеспечивать сопоставление файлов конкретных типов с атрибутами type_ N Каждый партнер несет ответственность за поддержание файлов сопоставления, если он собирается поддерживать N поставщиков с N+1 (или более поздней версией) system_ext и разделами продукта.

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

  1. Скопируйте сгенерированные файлы базового сопоставления из N разделов system_ext и продукта в их исходное дерево.
  2. При необходимости внесите изменения в файлы сопоставления.
  3. Установите файлы сопоставления в разделы system_ext и продукта 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 .
  • 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/.