На этой странице описывается, как Android обрабатывает проблемы совместимости политик при беспроводных обновлениях платформы (OTA), когда новые настройки SELinux платформы могут отличаться от старых настроек SELinux от производителя.
Право собственности на объекты и их маркировка
Для обеспечения разделения политик платформы и поставщика необходимо четко определить права собственности на каждый объект. Например, если политика поставщика присваивает метку /dev/foo , а политика платформы — метку /dev/foo в последующем обновлении OTA, это может привести к неопределенному поведению, например, к неожиданному отказу или, что более важно, к сбою загрузки. Для SELinux это проявляется как конфликт меток. Узел устройства может иметь только одну метку, которая разрешается в ту метку, которая была применена последней. В результате:
- Процессы, которым необходим доступ к неудачно примененной метке, теряют доступ к ресурсу.
- Процессы, получившие доступ к файлу, могут завершиться с ошибкой, поскольку был создан неправильный узел устройства.
Конфликты между метками платформы и поставщика могут возникать для любого объекта, имеющего метку SELinux, включая свойства, службы, процессы, файлы и сокеты. Чтобы избежать этих проблем, четко определите права собственности на эти объекты.
Пространства имен типов/атрибутов
Помимо конфликтов меток, могут возникать конфликты и имен типов и атрибутов SELinux. SELinux не допускает множественных объявлений одних и тех же типов и атрибутов. Политика с повторяющимися объявлениями не скомпилируется. Чтобы избежать конфликтов имен типов и атрибутов, настоятельно рекомендуется начинать все объявления поставщиков с префикса vendor_ . Например, поставщикам следует использовать type vendor_foo, domain; вместо type foo, domain; .
Право собственности на файл
Предотвращение конфликтов имен файлов представляет собой сложную задачу, поскольку политика платформы и поставщика обычно предоставляет метки для всех файловых систем. В отличие от именования типов, именование файлов в пространства имен непрактично, поскольку многие из них создаются ядром. Чтобы предотвратить эти конфликты, следуйте рекомендациям по именованию файловых систем, приведенным в этом разделе. Для Android 8.0 это рекомендации без технического контроля. В будущем эти рекомендации будут контролироваться с помощью набора тестов поставщика (VTS).
Система (/система)
Только образ системы должен содержать метки для компонентов /system через file_contexts , service_contexts и т. д. Если метки для компонентов /system добавлены в политику поставщика, обновление по воздуху только для фреймворка может быть невозможно.
Поставщик (/vendor)
Политика AOSP SELinux уже помечает части раздела vendor , с которым взаимодействует платформа, что позволяет писать правила SELinux для процессов платформы, чтобы они могли взаимодействовать или получать доступ к частям раздела 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, обеспечивающим сквозную передачу данных. - Все новые
exec_typesдобавленные в разделvendorчерез политику поставщика, должны иметь атрибутvendor_file_type. Это обеспечивается параметром neverallows. - Во избежание конфликтов с будущими обновлениями платформы/фреймворка, не следует присваивать файлам в разделе
vendorметки, отличные отexec_types. - Все библиотечные зависимости для HAL, идентифицированных в соответствии с AOSP и работающих в одном процессе, должны быть помечены как
same_process_hal_file.
Procfs (/proc)
Файлы в /proc могут быть помечены только с помощью метки genfscon . В Android 7.0 как политика платформы , так и политика поставщика использовали genfscon для маркировки файлов в procfs .
Рекомендация: Только политика платформы должна помечать /proc . Если процессам поставщика требуется доступ к файлам в /proc , которые в настоящее время помечены меткой по умолчанию ( proc ), политика поставщика не должна явно указывать на них метку, а вместо этого должна использовать общий тип proc для добавления правил для доменов поставщика. Это позволит обновлениям платформы учитывать будущие интерфейсы ядра, предоставляемые через procfs , и явно помечать их по мере необходимости.
Debugfs (/sys/kernel/debug)
Debugfs могут быть помечены как в file_contexts , так и genfscon . В Android 7.0–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 ).
Корневая файловая система (/)
Файлы в корневом каталоге / могут быть помечены в переменной file_contexts . В Android 7.0 здесь указываются метки файлов как платформой, так и производителем.
Рекомендация: Только система может присваивать метки файлам в корневом каталоге / .
Данные (/data)
Данные маркируются с помощью комбинации file_contexts и seapp_contexts .
Рекомендация: Запретить добавление меток поставщиков за пределами /data/vendor . Только платформа может добавлять метки в другие части /data .
Версия этикеток Genfs
Начиная с API поставщика уровня 202504, новые метки SELinux, назначенные с помощью genfscon в system/sepolicy/compat/plat_sepolicy_genfs_ ver .cil являются необязательными для разделов старых vendor . Это позволяет разделам старых vendor сохранять существующую реализацию 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 может использоваться разделами vendor , работающими с уровнем API 202404, либо с меткой sysfs по умолчанию, либо с меткой, специфичной для производителя. Безусловное присвоение /sys/class/udc метки sysfs_udc может нарушить совместимость с этими разделами vendor . Проверка параметра BOARD_GENFS_LABELS_VERSION позволяет платформе продолжать использовать предыдущие метки и разрешения для более старых разделов vendor .
BOARD_GENFS_LABELS_VERSION может быть больше или равно уровню API поставщика. Например, для разделов vendor , использующих уровень API 202404, можно установить BOARD_GENFS_LABELS_VERSION равным 202504, чтобы использовать новые метки, введенные в версии 202504. См. список меток genfs, специфичных для версии 202504 .
При присвоении меток узлам genfscon платформа должна учитывать разделы более старых vendor и реализовывать механизмы резервного копирования для обеспечения совместимости при необходимости. Платформа может использовать библиотеки, доступные только на платформе, для запроса версии меток genfs.
- В нативных приложениях используйте
libgenfslabelsversion. Заголовочный файлlibgenfslabelsversionможно найти в файлеgenfslabelsversion.h. - В Java используйте
android.os.SELinux.getGenfsLabelsVersion().
Политика публичной платформы
Политика SELinux для платформы делится на частную и публичную. Политика platform-public состоит из типов и атрибутов, которые всегда доступны на уровне API поставщика , выступая в качестве API между платформой и поставщиком. Эта политика предоставляется разработчикам политик поставщиков, чтобы позволить поставщикам создавать файлы политик, которые в сочетании с политикой platform-private приводят к созданию полностью функциональной политики для устройства. Политика platform-public определяется в system/sepolicy/public .
Например, тип vendor_init , представляющий процесс инициализации в контексте поставщика, определен в файле system/sepolicy/public/vendor_init.te :
type vendor_init, domain;
Поставщики могут использовать тип vendor_init для написания пользовательских правил политики:
# Allow vendor_init to set vendor_audio_prop in vendor's init scripts
set_prop(vendor_init, vendor_audio_prop)Атрибуты совместимости
Политика SELinux — это взаимодействие между типами источника и цели для определенных классов объектов и разрешений. Каждый объект (например, процессы, файлы), на который распространяется политика SELinux, может иметь только один тип, но этот тип может иметь несколько атрибутов.
Политика написана преимущественно на основе существующих типов. В данном случае vendor_init и debugfs являются типами:
allow vendor_init debugfs:dir { mounton };
Это работает, потому что политика была написана с учетом всех типов. Однако, если политика поставщика и политика платформы используют определенные типы, и метка конкретного объекта изменяется только в одной из этих политик, другая может содержать политику, которая получила или потеряла доступ, на который ранее полагались. Например, предположим, что политика платформы помечает узлы sysfs как sysfs :
/sys(/.*)? u:object_r:sysfs:s0
Политика поставщика предоставляет доступ к /sys/usb , помеченному как sysfs :
allow vendor_init sysfs:chr_file rw_file_perms;
Если политика платформы будет изменена таким образом, чтобы /sys/usb помечался как sysfs_usb , политика поставщика останется прежней, но vendor_init потеряет доступ к /sys/usb из-за отсутствия политики для нового типа sysfs_usb :
/sys/usb u:object_r:sysfs_usb:s0
Для решения этой проблемы Android вводит концепцию версионированных атрибутов. Во время компиляции система сборки автоматически преобразует общедоступные типы платформы, используемые в политике поставщика, в эти версионированные атрибуты. Это преобразование обеспечивается путем сопоставления файлов, которые связывают версионированный атрибут с одним или несколькими общедоступными типами платформы.
Например, предположим, что /sys/usb помечен как sysfs в политике платформы 202504, а политика поставщика 202504 предоставляет vendor_init доступ к /sys/usb . В этом случае:
- Политика поставщика создает правило
allow vendor_init sysfs:chr_file rw_file_perms;, поскольку/sys/usbпомечен какsysfsв политике платформы 202504. Когда система сборки компилирует политику поставщика, она автоматически преобразует правило вallow vendor_init _202504 sysfs _202504 :chr_file rw_file_perms;. Атрибутыvendor_init_202504иsysfs_202504соответствуют типамvendor_initиsysfs, которые определены платформой. - Система сборки генерирует файл сопоставления идентификаторов
/system/etc/selinux/mapping/202504.cil. Посколькуsystemиvendorразделы используют одну и ту же версию202504, файл сопоставления содержит сопоставления идентификаторов отtype_202504кtype. Например,vendor_init_202504сопоставляется сvendor_init, аsysfs_202504— сsysfs:(typeattributeset sysfs_202504 (sysfs)) (typeattributeset vendor_init_202504 (vendor_init)) ...
При повышении версии с 202504 до 202604 создается новый файл сопоставления для разделов vendor версии 202504 в каталоге system/sepolicy/private/compat/202504/202504.cil , который устанавливается в /system/etc/selinux/mapping/202504.cil для system разделов версии 202604 или более новых. Первоначально этот файл сопоставления содержит сопоставления идентификаторов, как описано ранее. Если в политику платформы 202604 добавляется новая метка sysfs_usb для /sys/usb , файл сопоставления обновляется, чтобы сопоставить sysfs_202504 с sysfs_usb :
(typeattributeset sysfs_202504 (sysfs sysfs_usb)) (typeattributeset vendor_init_202504 (vendor_init)) ...
Это обновление позволяет преобразованному правилу политики поставщика allow vendor_init_202504 sysfs_202504:chr_file rw_file_perms; автоматически предоставлять vendor_init доступ к новому типу sysfs_usb .
Для обеспечения совместимости со старыми разделами vendor , при добавлении нового общедоступного типа этот тип должен быть сопоставлен как минимум с одним из версионированных атрибутов в файле сопоставления system/sepolicy/private/compat/ ver / ver .cil или указан в system/sepolicy/private/compat/ ver / ver .ignore.cil , чтобы указать, что в предыдущих версиях поставщика нет соответствующего типа.
Сочетание политики платформы, политики поставщика и файла сопоставления позволяет системе обновляться без обновления политики поставщика. Кроме того, преобразование в версионированные атрибуты происходит автоматически, поэтому политике поставщика не нужно заботиться о версионировании, и общедоступные типы остаются неизменными.
политика общедоступных ресурсов системы_ext и политика общедоступных продуктов
Начиная с Android 11, разделы system_ext и product могут экспортировать свои назначенные общедоступные типы в раздел vendor . Подобно политике общедоступных типов платформы, политика vendor использует типы и правила, автоматически преобразуемые в версионированные атрибуты, например, из type в type_ ver , где ver — это уровень API раздела vendor .
Когда разделы system_ext и product основаны на одной и той же версии платформы ver , система сборки генерирует файлы сопоставления базовых значений для system_ext/etc/selinux/mapping/ ver .cil и product/etc/selinux/mapping/ ver .cil , которые содержат сопоставления идентификаторов от type к type_ ver . Политика поставщика может получить доступ type с помощью атрибута версии type_ ver .
В случае, если обновляются только разделы system_ext и product , например, ver до ver+1 (или более поздней версии), а раздел vendor остается в версии ver , политика поставщика может потерять доступ к типам разделов system_ext и product . Для предотвращения сбоев разделы system_ext и product должны предоставлять файлы сопоставления конкретных типов с атрибутами type_ ver . Каждый партнер несет ответственность за поддержание файлов сопоставления, если он поддерживает раздел vendor ver с разделами system_ext и product версии ver+1 (или более поздней).
Для установки файлов сопоставления в разделы system_ext и разделы product от разработчиков устройств или поставщиков ожидается следующее:
- Скопируйте сгенерированные файлы сопоставления базовых файлов из разделов ver
system_extиproductв их исходное дерево . - При необходимости внесите изменения в файлы сопоставления.
- Установите файлы сопоставления в разделы
system_extиproductver+1 (или более поздней).
Например, предположим, что в разделе system_ext 202504 есть один публичный тип с именем foo_type . Тогда system_ext/etc/selinux/mapping/202504.cil в разделе system_ext 202504 выглядит следующим образом:
(typeattributeset foo_type_202504 (foo_type)) (expandtypeattribute foo_type_202504 true) (typeattribute foo_type_202504)
Если параметр bar_type добавлен к system_ext 202604, и если bar_type должен быть сопоставлен с foo_type для раздела vendor 202504, то 202504.cil можно обновить с (typeattributeset foo_type_202504 (foo_type)) на (typeattributeset foo_type_202504 (foo_type bar_type)) , а затем установить в раздел system_ext 202604. Раздел vendor 202504 сможет продолжать обращаться к foo_type и bar_type из system_ext 202604.
Изменения атрибутов для 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. Атрибут для всех системных доменов (кромеshell domainsinitи оболочки), которые нарушают требование не выполнять бинарные файлы сторонних поставщиков. Выполнение бинарных файлов сторонних поставщиков имеет нестабильный API. Платформа не должна выполнять бинарные файлы сторонних поставщиков напрямую. Рекомендация:- Подобные зависимости платформы от исполняемых файлов поставщиков должны быть скрыты за HAL-интерфейсами HIDL.
ИЛИ
-
coredomains, которым необходим доступ к исполняемым файлам сторонних поставщиков, следует переместить в раздел,vendor, и таким образом перестать бытьcoredomain.
- Подобные зависимости платформы от исполняемых файлов поставщиков должны быть скрыты за HAL-интерфейсами HIDL.
Ненадежные атрибуты
Ненадежные приложения, содержащие произвольный код, не должны иметь доступа к службам HwBinder, за исключением тех, которые считаются достаточно безопасными для доступа из таких приложений (см. безопасные службы ниже). Две основные причины этого:
- Серверы HwBinder не выполняют аутентификацию клиентов, поскольку HIDL в настоящее время не раскрывает информацию об UID вызывающего абонента. Даже если бы HIDL раскрывал такие данные, многие службы HwBinder либо работают на уровне ниже приложений (например, HAL), либо не должны полагаться на идентификацию приложения для авторизации. Таким образом, для обеспечения безопасности по умолчанию предполагается, что каждая служба HwBinder рассматривает всех своих клиентов как одинаково авторизованных для выполнения операций, предлагаемых службой.
- Серверы HAL (подмножество сервисов HwBinder) содержат код с более высокой частотой возникновения проблем безопасности, чем
system/coreкомпоненты, и имеют доступ к нижним уровням стека (вплоть до оборудования), что увеличивает возможности для обхода модели безопасности Android.
Безопасные услуги
К услугам обеспечения безопасности относятся:
-
same_process_hwservice. Эти службы (по определению) выполняются в процессе клиента и, следовательно, имеют тот же доступ, что и домен клиента, в котором выполняется процесс. -
coredomain_hwservice. Эти сервисы не представляют рисков, связанных с причиной №2. -
hal_configstore_ISurfaceFlingerConfigs. Этот сервис специально разработан для использования любым доменом. -
hal_graphics_allocator_hwservice. Эти операции также предоставляются службойsurfaceflingerBinder, к которой приложениям разрешен доступ. -
hal_omx_hwservice. Это версия службыmediacodecBinder, использующая протокол HwBinder, к которой приложениям разрешен доступ. -
hal_codec2_hwservice. Это более новая версияhal_omx_hwservice.
Полезные атрибуты
Все hwservices не считающиеся безопасными, имеют атрибут untrusted_app_visible_hwservice . Соответствующие HAL-серверы имеют атрибут untrusted_app_visible_halserver . Устройства, запускаемые с Android 9, НЕ ДОЛЖНЫ использовать ни один из атрибутов untrusted .
Рекомендация:
- Вместо этого ненадежные приложения должны взаимодействовать с системной службой, которая, в свою очередь, взаимодействует с HAL HIDL от поставщика. Например, приложения могут взаимодействовать с
binderservicedomain, а затемmediaserver(который являетсяbinderservicedomain) взаимодействует сhal_graphics_allocator.ИЛИ
- Приложениям, которым необходим прямой доступ к HAL-интерфейсам
vendor, следует иметь собственный домен политики безопасности, определяемый поставщиком.
Тесты атрибутов файлов
В Android 9 включены тесты, выполняемые на этапе сборки , которые гарантируют, что все файлы в определенных местах имеют соответствующие атрибуты (например, все файлы в sysfs имеют необходимый атрибут sysfs_type ).
маркировка контекстов 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от поставщика.
- Специфичный для платформы Android
-
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- В
hwservice_contextплатформы Android для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при запуске.
-
Контексты Seapp
В Android 8.0 файл seapp_contexts разделен на два файла:
-
plat_seapp_contexts-
seapp_contextдля платформы Android, не содержащий изменений, специфичных для конкретного устройства. - Должен находиться в
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 разделен на два файла:
- Platform
mac_permissions.xml- Файл
mac_permissions.xmlплатформы Android, не содержащий изменений, специфичных для конкретного устройства. - Должен находиться в
systemразделе по адресу/system/etc/selinux/.
- Файл
- Non-Platform
mac_permissions.xml- Расширение, специфичное для устройства, для файла
mac_permissions.xmlплатформы, созданное на основе файлаmac_permissions.xml, расположенного в каталогах, на которые указывает параметрBOARD_SEPOLICY_DIRSв файлахBoardconfig.mkустройства. - Должен находиться в разделе
vendorпо адресу/vendor/etc/selinux/.
- Расширение, специфичное для устройства, для файла
Изменения в общей памяти для Android 17
Начиная с Android 17, устройства, запускаемые со следующими свойствами, должны включить возможность политики memfd_class и обновить свою политику, связанную с разделяемой памятью, для поддержки объектов класса memfd_file :
- Уровень API поставщика 202604 или выше предоставляет поставщикам и OEM-производителям возможность обновить свою политику поставщика для поддержки
memfd. Это также позволяет существующим устройствам обновляться до более высоких версий Android без необходимости обновления раздела поставщика. - Ядро
android16-6.12или более поздней версии, поскольку эти ядра поддерживают функциюmemfd_class, необходимую для реализации детальной политики дляmemfd.
Включите возможность политики memfd_class.
До недавнего времени SELinux помечал memfd как файл того же типа, что и базовая файловая система — tmpfs. Это делало невозможным различение memfd от другого файла на монтированной файловой системе tmpfs с точки зрения политик. Теперь SELinux помечает memfd контекстом безопасности выделяющего процесса, и memfds рассматриваются как объекты класса memfd_file . Эта функциональность защищена возможностью политики memfd_class , что обеспечивает обратную совместимость со старыми средами пользовательского пространства.
Для включения возможности политики memfd_class создайте файл policy_capabilities в каталоге BOARD_VENDOR_SEPOLICY_DIRS . Файл должен содержать следующую запись:
# $BOARD_VENDOR_SEPOLICY_DIRS/*/policy_capabilities
policycap memfd_class;Затем пересоберите образы и загрузите их на устройство, чтобы убедиться, что эта функция включена.
Убедитесь, что функция политики memfd_class включена.
Для проверки состояния параметра политики memfd_class используйте следующую команду:
adb shell 'cat /sys/fs/selinux/policy_capabilities/memfd_class'
Если результат равен 1 , то возможность политики memfd_class включена. В противном случае она не включена.
Перевести существующую политику на memfd
Некоторые процессы использовали макрос tmpfs_domain() в своей политике для доступа к своим memfds и создания пространств имен, например:
# foo.te
tmpfs_domain(foo)Это переводится как:
# foo.te type_transition foo tmpfs:file foo_tmpfs; allow foo foo_tmpfs:file { read write getattr map };
и давайте обработаем процесс bar и получим доступ к memfds процесса foo следующим образом:
# bar.te allow bar foo_tmpfs:file { read write getattr map };
При включении возможности политики memfd_class макрос tmpfs_domain() больше не требуется, поскольку политика платформы была обновлена и позволяет любому процессу создавать и использовать собственные memfds , как показано здесь:
# system/sepolicy/private/domain.te allow domain self:memfd_file { create read write getattr map };
А memfds созданные процессом foo могут быть доступны из bar процессов следующим образом:
# bar.te allow bar foo:memfd_file { read write getattr map };
Политика платформы была обновлена с учетом существующего использования memfd . Однако политика, специфичная для производителя и устройства и использующая метки tmpfs , должна быть обновлена для использования memfd_file . Если политика используется совместно SoC или устройствами, не имеющими API уровня 202604 или выше, рекомендуется сохранить устаревшую политику tmpfs вместе с новой политикой memfd_file для обеспечения совместимости.
Выявление отказов AVC, связанных с memfd.
Сообщения об отказах, связанных с Memfd можно получить с помощью следующей команды:
adb shell logcat -d -b events | grep memfd
AVC-отказы с использованием tmpfs в качестве цели
Следующий пример демонстрирует отказ avc , с которым столкнулся процесс, пытавшийся записать данные в memfd , на запись в который у него не было разрешения:
audit(0.0:539): avc: denied { write } for comm="binder:665_1" name="memfd:MessageQueue"
dev="tmpfs" ino=8324 scontext=u:r:mediacodec:s0 tcontext=u:object_r:tmpfs:s0 tclass=file
permissive=0Когда включена возможность применения политики memfd_class , целевым контекстом memfd является контекст безопасности выделяющего процесса, а не tmpfs , и целевым классом является memfd_file , а не file . Поэтому, если вы наблюдаете отказы avc связанные с memfd , где рассматриваемый memfd помечен как файл tmpfs , возможность применения политики memfd_class не включена.
Отказы AVC с целевым классом memfd_file
В следующем примере показан отказ avc , с которым столкнулся процесс, пытавшийся записать данные в memfd , на который у него не было разрешения на запись, при включенной возможности политики memfd_class , а также дополнительная строка, которую logd выводит после отказа с той же меткой времени:
audit(0.0:86): avc: denied { read } for
path=2F6D656D66643A4D6564696142756666657247726F7570202864656C6574656429 ino=512 dev=""
scontext=u:r:mediaserver:s0 tcontext=u:object_r:mediaextractor:s0 tclass=memfd_file
auditd : Decoded path for audit(0.0:86): /memfd:MediaBufferGroup (deleted)Соответствующая метка времени указывает на то, что Decoded path for … log связан с отказом avc с меткой времени 0.0.86 . Этот лог декодирует шестнадцатеричную строку из значения пути в отказе avc и предоставляет имя области памяти memfd , что может быть полезно для понимания того, какой буфер используется совместно. Исходный контекст и целевой контекст полезны для понимания того, каким процессам необходимо совместно использовать память. Из приведенного выше примера ясно, что процессу mediaserver необходимо иметь доступ к memfds mediaextractor . Следовательно, соответствующая политика следующая:
# mediaserver.te allow mediaserver mediaextractor:memfd_file { getattr read write map };
Обновления доменов безопасности в Android 17
API ASharedMemory_create() в Android 17 реализует условную логику для выбора между устаревшим драйвером ashmem и фреймворком memfd при выделении общей памяти.
Для устройств, соответствующих требованиям memfd (уровень API поставщика 202604 или выше и ядро android16-6.12 или новее), API оценивает targetSdkVersion вызывающего приложения. Если целевая версия SDK равна 37 или выше, выделяется memfd . Это позволяет разработчикам исправлять проблемы, возникающие при обновлении целевой версии SDK.
Если устройство не соответствует требованиям memfd's , ASharedMemory переключается на ashmem. Это обеспечивает совместимость обновленных устройств со старыми разделами или ядрами от разных производителей.
Для обеспечения этого перехода политика SELinux платформы блокирует приложениям, ориентированным на версию SDK 37 или выше, в доменах безопасности platform_app , priv_app и untrusted_app , запрещая им открывать /dev/ashmem и вызывать команды ioctl ashmem на memfd . Это достигается путем разделения этих доменов приложений в зависимости от целевой версии SDK. В результате появляются домены безопасности platform_app_36 , priv_app_36 и untrusted_app_34 , которые, наряду с другими доменами приложений, сохраняют разрешения на открытие ashmem и возможность вызывать команды ioctl ashmem на memfds .
В будущей версии Android набор приложений, сохраняющих разрешения на открытие устройства ashmem и выполнение команд ioctl ashmem на memfds будет сокращен до platform_app_36 , priv_app_36 и untrusted_app_34 , а также до доменов ненадежных приложений для более старых версий SDK.
Пользовательские политики SELinux от поставщика или OEM-производителя для приложений, которые фиксируют целевую версию SDK, должны быть обновлены в соответствии с этими изменениями домена, как подробно описано в следующих разделах.
обновления домена SELinux для платформы_приложения
Домен platform_app разделяется в зависимости от targetSdkVersion приложения. Приложениям, ориентированным на SDK версии 37 или выше, назначается домен platform_app , а приложениям, ориентированным на SDK версии 36 или ниже, — домен platform_app_36 . Домен platform_app_36 сохраняет возможность открытия /dev/ashmem для обратной совместимости. Для упрощения управления политиками в обоих доменах используйте атрибут platform_app_all .
Рассмотрим случай, когда приложению-платформе sample-plat-app необходимо читать и записывать данные в /dev/foo_device . Существующая политика SELinux от поставщика может выглядеть следующим образом:
# This will only allow sample-plat-app to access the device if it # is placed in the platform_app domain (i.e. target SDK version is 37 or higher). allow platform_app foo_device:chr_file rw_file_perms;
Однако, если sample-plat-app привязан к целевой версии SDK 36, он помещается в домен platform_app_36 , и политика SELinux, примененная ранее, не будет действовать, в результате чего будет наблюдаться следующее сообщение об отказе AVC:
auditd : type=1400 audit(0.0:11): avc: denied { read write } for comm="sample-plat-app" path="/dev/foo_device" dev="tmpfs" ino=1609 scontext=u:r:platform_app_36:s0:c512,c768 tcontext=u:object_r:foo_device:s0 tclass=chr_file permissive=0
Для решения этой проблемы политику можно обновить следующим образом, поскольку приложение всегда должно иметь доступ к узлу устройства:
# This allows sample-plat-app to access the device independent of # target SDK version. allow platform_app_all foo_device:chr_file rw_file_perms;
В некоторых ситуациях platform_app_all может не работать. Например, если макрос hal_client_domain() используется с platform_app_all , политика не компилируется. Это происходит потому, что platform_app_all является атрибутом, и hal_client_domain() попытается прикрепить к нему другой атрибут, что невозможно:
# platform_app.te
hal_client_domain(platform_app, hal_foo)В таких сценариях необходимо использовать тип platform_app_36 напрямую, поэтому ваша политика будет содержать следующее:
# platform_app.te hal_client_domain(platform_app, hal_foo) # platform_app_36.te hal_client_domain(platform_app_36, hal_foo)
Обновления домена SELinux для priv_app
Домен priv_app разделяется в зависимости от targetSdkVersion приложения. Привилегированным приложениям, ориентированным на SDK версии 37 или выше, назначается домен priv_app , а приложениям, ориентированным на SDK версии 36 или ниже, — домен priv_app_36 . Домен priv_app_36 сохраняет возможность открытия /dev/ashmem для обратной совместимости. Для упрощения управления политиками в обоих доменах используйте атрибут priv_app_all .
Рассмотрим случай, когда приложению-платформе sample-priv-app необходимо читать и записывать данные в /dev/foo_device . Существующая политика SELinux от поставщика может выглядеть следующим образом:
# This will only allow sample-priv-app to access the device if it # is placed in the priv_app domain (i.e. target SDK version is 37 or higher). allow priv_app foo_device:chr_file rw_file_perms;
Однако, если sample-priv-app привязан к целевой версии SDK 36, он помещается в домен priv_app_36 , и политика SELinux, примененная ранее, не будет действовать, в результате чего будет наблюдаться следующее сообщение об отказе AVC:
auditd : type=1400 audit(0.0:11): avc: denied { read write } for comm="sample-priv-app" path="/dev/foo_device" dev="tmpfs" ino=1609 scontext=u:r:priv_app_36:s0:c512,c768 tcontext=u:object_r:foo_device:s0 tclass=chr_file permissive=0
Для решения этой проблемы политику можно обновить следующим образом, поскольку приложение всегда должно иметь доступ к узлу устройства:
# This allows sample-priv-app to access the device independent of # target SDK version. allow priv_app_all foo_device:chr_file rw_file_perms;
В некоторых ситуациях priv_app_all может не работать. Например, если макрос hal_client_domain() используется с priv_app_all , политика не будет скомпилирована. Это связано с тем, что priv_app_all является атрибутом, и hal_client_domain() попытается прикрепить к нему другой атрибут, что невозможно:
# priv_app.te
hal_client_domain(priv_app, hal_foo)In those scenarios, it is required to use the priv_app_36 type directly, so your policy files will look something like this:
# priv_app.te hal_client_domain(priv_app, hal_foo) # priv_app_36.te hal_client_domain(priv_app_36, hal_foo)
untrusted_app SELinux domain updates
The untrusted_app domain is split based on the app's targetSdkVersion . Untrusted apps targeting SDK 37 version or higher are assigned the untrusted_app domain, while those targeting SDK versions 34-36 inclusive are assigned the new untrusted_app_34 domain. The untrusted_app_34 domain, as well as the untrusted_app_X domains, where `X` is an older target SDK version, retain the ability to open `/dev/ashmem` for backward compatibility.