Создание политики SELinux

В этой статье рассказывается, как строится политика SELinux. Политика SELinux построена на основе комбинации базовой политики AOSP (платформы) и политики для конкретного устройства (поставщика). Процесс сборки политики SELinux для Android 4.4–Android 7.0 объединял все фрагменты sepolicy, а затем создавал монолитные файлы в корневом каталоге. Это означало, что поставщики SoC и производители ODM изменяли boot.img (для устройств, отличных от A/B) или system.img (для устройств A/B) каждый раз, когда была изменена политика.

В Android 8.0 и более поздних версиях политика платформы и поставщика создается отдельно. SOC и OEM-производители могут обновлять свои части политики, создавать свои образы (например, vendor.img и boot.img ), а затем обновлять эти образы независимо от обновлений платформы.

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

Исходные файлы

Логика сборки SELinux находится в этих файлах:

  • external/selinux : внешний проект SELinux, используемый для создания утилит командной строки HOST для компиляции политики и меток SELinux.
    • external/selinux/libselinux : Android использует только подмножество внешнего проекта libselinux вместе с некоторыми настройками, специфичными для Android. Подробности см. в external/selinux/README.android .
    • external/selinux/libsepol :
      • chkcon : определяет, действителен ли контекст безопасности для данной двоичной политики (исполняемого файла хоста).
      • libsepol : библиотека SELinux для управления бинарными политиками безопасности (хостовая статическая/общая библиотека, целевая статическая библиотека).
    • external/selinux/checkpolicy : компилятор политики SELinux (исполняемые файлы хоста: checkpolicy , checkmodule и dispol ). Зависит от libsepol .
  • system/sepolicy : основные конфигурации политик Android SELinux, включая контексты и файлы политик. Основная логика сборки sepolicy также находится здесь ( system/sepolicy/Android.mk ).

Для получения более подробной информации о файлах в system/sepolicy Реализация SELinux .

Android 7.0 и более ранние версии

В этом разделе описывается, как политика SELinux построена в Android 7.x и более ранних версиях.

Создание политики SELinux

Политика SELinux создается путем объединения базовой политики AOSP с настройками для конкретного устройства. Объединенная политика затем передается компилятору политики и различным средствам проверки. Настройка для конкретного устройства осуществляется с помощью переменной BOARD_SEPOLICY_DIRS , определенной в файле Boardconfig.mk для конкретного устройства. Эта глобальная переменная сборки содержит список каталогов, определяющих порядок поиска дополнительных файлов политики.

Например, поставщик SoC и ODM могут добавить каталог: один для настроек SoC, а другой для настроек конкретного устройства, чтобы сгенерировать окончательные конфигурации SELinux для данного устройства:

  • BOARD_SEPOLICY_DIRS += device/ SOC /common/sepolicy
  • BOARD_SEPOLICY_DIRS += device/ SoC / DEVICE /sepolicy

Содержимое файлов file_contexts в system/sepolicy и BOARD_SEPOLICY_DIRS объединяется для создания файла file_contexts.bin на устройстве:

На этом изображении показана логика сборки SELinux для Android 7.x.
Рисунок 1 . Логика сборки SELinux

Файл sepolicy состоит из нескольких исходных файлов:

  • Простой текстовый policy.conf создается путем объединения security_classes , initial_sids , *.te , genfs_contexts и port_contexts в указанном порядке.
  • Содержимое каждого файла (например, security_classes ) представляет собой объединение файлов с одинаковым именем в разделах system/sepolicy/ и BOARDS_SEPOLICY_DIRS .
  • policy.conf отправляется компилятору SELinux для проверки синтаксиса и компилируется в двоичный формат как sepolicy на устройстве.
    На этом изображении показаны файлы, генерирующие файл политики SELinux для Android 7.x.
    Фигура 2 . Файл политики SELinux

файлы SELinux

После компиляции устройства Android под управлением версии 7.x и более ранних версий обычно содержат следующие файлы, связанные с SELinux:

  • selinux_version
  • sepolicy: двоичный вывод после объединения файлов политики (таких как security_classes , initial_sids и *.te )
  • file_contexts
  • property_contexts
  • seapp_contexts
  • service_contexts
  • system/etc/mac_permissions.xml

Дополнительные сведения см. в разделе «Реализация SELinux» .

Инициализация SELinux

Когда система загружается, SELinux находится в разрешающем режиме (а не в принудительном режиме). Процесс инициализации выполняет следующие задачи:

  • Загружает файлы sepolicy с виртуального диска в ядро ​​через /sys/fs/selinux/load .
  • Переключает SELinux в принудительном режиме.
  • Запускает re-exec() , чтобы применить к себе правило домена SELinux.

Чтобы сократить время загрузки, как можно скорее выполните re-exec() в процессе init .

Андроид 8.0 и выше

В Android 8.0 политика SELinux разделена на компоненты платформы и поставщика, чтобы обеспечить возможность независимого обновления политики платформы/поставщика при сохранении совместимости.

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

Общественная политика платформы

Публичная политика безопасности платформы включает в себя все, что определено в разделе system/sepolicy/public . Платформа может предполагать, что типы и атрибуты, определенные в соответствии с публичной политикой, являются стабильными API для данной версии платформы. Это составляет часть политики sepolicy, которая экспортируется платформой, на которой разработчики политики поставщика (т. е. устройства) могут писать дополнительную политику для конкретного устройства.

Версии типов определяются в соответствии с версией политики, в соответствии с которой записываются файлы поставщика, определенной переменной сборки PLATFORM_SEPOLICY_VERSION . Публичная политика с поддержкой версий затем включается в политику поставщика и (в исходной форме) в политику платформы. Таким образом, окончательная политика включает в себя политику частной платформы, общедоступную политику конфиденциальности текущей платформы, политику, специфичную для устройства, и общедоступную политику с указанием версий, соответствующую версии платформы, для которой была написана политика устройства.

Политика конфиденциальности платформы

Частная политика платформы включает в себя все, что определено в /system/sepolicy/private . Эта часть политики формирует типы, разрешения и атрибуты, доступные только для платформы, необходимые для функциональности платформы. Они не экспортируются разработчикам политики vendor/device . Авторы политик, не являющиеся платформой, не должны писать расширения своих политик на основе типов/атрибутов/правил, определенных в частной политике платформы. Более того, эти правила можно изменять или они могут исчезнуть в рамках обновления только платформы.

Частное картографирование платформы

Частное сопоставление платформы включает в себя заявления политики, которые сопоставляют атрибуты, представленные в общедоступной политике платформы предыдущих версий платформы, с конкретными типами, используемыми в текущей общедоступной политике безопасности платформы. Это гарантирует, что политика поставщика, написанная на основе общедоступных атрибутов платформы из предыдущих версий общедоступной политики Sepolicy платформы, продолжает работать. Управление версиями основано на переменной сборки PLATFORM_SEPOLICY_VERSION , установленной в AOSP для данной версии платформы. Для каждой предыдущей версии платформы существует отдельный файл сопоставления, от которого ожидается, что эта платформа будет принимать политику поставщика. Более подробную информацию см. в разделе «Совместимость» .

Андроид 11 и выше

system_ext и политика безопасности продукта

В Android 11 добавлены политика system_ext и политика продукта. Как и политика безопасности платформы, политика system_ext и политика продукта разделены на публичную и частную политику.

Публичная политика экспортируется поставщику. Типы и атрибуты становятся стабильным API, а политика поставщика может ссылаться на типы и атрибуты в общедоступной политике. Типы имеют версии в соответствии с PLATFORM_SEPOLICY_VERSION , а политика версий включена в политику поставщика. Исходная политика включена в каждый раздел system_ext и продукт.

Частная политика содержит типы, разрешения и атрибуты только для system_ext и только для продукта, необходимые для функциональности разделов system_ext и продукта. Частная политика невидима для поставщика, а это означает, что эти правила являются внутренними и их можно изменять.

system_ext и сопоставление продуктов

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

  • Чтобы установить файл сопоставления для system_ext, поместите файл cil, содержащий нужную информацию о сопоставлении, в {SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil , а затем добавьте system_ext_{ver}.cil в PRODUCT_PACKAGES .
  • Чтобы установить файл сопоставления для продукта, поместите файл cil, содержащий нужную информацию о сопоставлении, в {PRODUCT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil , а затем добавьте product_{ver}.cil в PRODUCT_PACKAGES .
  • Обратитесь к примеру , в котором добавляется файл сопоставления раздела продукта устройства Redbull.

    Создание политики SELinux

    Политика SELinux в Android 8.0 создана путем объединения частей /system и /vendor . Логика правильной настройки находится в /platform/system/sepolicy/Android.mk .

    Политика существует в следующих местах:

    Расположение Содержит
    system/sepolicy/public API sepolicy платформы
    system/sepolicy/private Детали реализации платформы (поставщики могут игнорировать)
    system/sepolicy/vendor Файлы политики и контекста, которые могут использовать поставщики (при желании поставщики могут игнорировать)
    BOARD_SEPOLICY_DIRS Политика конфиденциальности в отношении поставщиков
    BOARD_ODM_SEPOLICY_DIRS (Android 9 и выше) Политика конфиденциальности
    SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 и выше) API sepolicy System_ext
    SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 и выше) Детали реализации System_ext (поставщики могут игнорировать)
    PRODUCT_PUBLIC_SEPOLICY_DIRS (Android 11 и более поздних версий) API sepolicy продукта
    PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 11 и более поздних версий) Подробности реализации продукта (поставщики могут игнорировать)

    Система сборки принимает эту политику и создает компоненты политики system, system_ext, Product, Vendor и odm в соответствующем разделе. Шаги включают в себя:

    1. Преобразование политик в формат SELinux Common Intermediate Language (CIL), а именно:
      1. политика общедоступной платформы (система + system_ext + продукт)
      2. комбинированная частная + государственная политика
      3. общедоступная + политика поставщика и BOARD_SEPOLICY_DIRS
    2. Управление версиями политики, предоставляемой общедоступно как часть политики поставщика. Выполняется с использованием созданной общедоступной политики CIL для информирования объединенной политики общедоступного + поставщика + BOARD_SEPOLICY_DIRS о том, какие части должны быть преобразованы в атрибуты, которые будут связаны с политикой платформы.
    3. Создание файла сопоставления, связывающего части платформы и поставщика. Первоначально это просто связывает типы из общедоступной политики с соответствующими атрибутами в политике поставщика; позже он также станет основой для файла, поддерживаемого в будущих версиях платформы, обеспечивая совместимость с политикой поставщика, ориентированной на эту версию платформы.
    4. Объединение файлов политики (опишите как встроенные в устройство, так и предварительно скомпилированные решения).
      1. Объедините картографию, платформу и политику поставщика.
      2. Скомпилируйте выходной двоичный файл политики.

    Предварительно скомпилированная политика SELinux

    Прежде чем init включит SELinux, init собирает все файлы CIL из разделов ( system , system_ext , product , vendor и odm ) и компилирует их в двоичную политику, формат, который можно загрузить в ядро. Поскольку компиляция занимает время (обычно 1-2 секунды), файлы CIL предварительно компилируются во время сборки и помещаются либо в /vendor/etc/selinux/precompiled_sepolicy либо /odm/etc/selinux/precompiled_sepolicy вместе с хэшами sha256. входных файлов CIL. Во время выполнения init проверяет, был ли обновлен какой-либо файл политики, сравнивая хэши. Если ничего не изменилось, init загружает предварительно скомпилированную политику. Если нет, init компилируется на лету и использует его вместо предварительно скомпилированного.

    Точнее, предварительно скомпилированная политика используется, если соблюдены все следующие условия. Здесь {partition} представляет раздел, в котором существует предварительно скомпилированная политика: либо vendor , либо odm .

    • Оба файла /system/etc/selinux/plat_sepolicy_and_mapping.sha256 и /{partition}/etc/selinux/precompiled_sepolicy.plat_sepolicy_and_mapping.sha256 существуют и идентичны.
    • Оба /system_ext/etc/selinux/system_ext_sepolicy_and_mapping.sha256 и /{partition}/etc/selinux/precompiled_sepolicy.system_ext_sepolicy_and_mapping.sha256 не существуют. Или оба существуют и идентичны.
    • Оба /product/etc/selinux/product_sepolicy_and_mapping.sha256 и /{partition}/etc/selinux/precompiled_sepolicy.product_sepolicy_and_mapping.sha256 не существуют. Или оба существуют и идентичны.

    Если какой-либо из них отличается, init возвращается к пути компиляции на устройстве. Дополнительную информацию см. в system/core/init/selinux.cpp .