Внедрить SELinux

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

Ключевые файлы

Для включения SELinux необходимо интегрировать последнюю версию ядра Android , а затем добавить файлы, находящиеся в каталоге system/sepolicy . После компиляции эти файлы образуют политику безопасности ядра SELinux и охватывают основную операционную систему Android.

В целом, не следует напрямую изменять файлы system/sepolicy . Вместо этого добавьте или отредактируйте собственные файлы политик, специфичные для вашего устройства, в каталоге /device/ manufacturer / device-name /sepolicy . В Android 8.0 и выше изменения, внесенные в эти файлы, должны затрагивать только политики в каталоге поставщика. Более подробную информацию о разделении общедоступных файлов sepolicy в Android 8.0 и выше см. в разделе «Настройка SEPolicy в Android 8.0+» . Независимо от версии Android, вы все равно изменяете эти файлы:

Файлы политики

Файлы с расширением *.te — это исходные файлы политик SELinux, определяющие домены и их метки. Возможно, вам потребуется создать новые файлы политик в каталоге /device/ manufacturer / device-name /sepolicy , но по возможности следует обновить существующие файлы.

Контекстные файлы

В файлах контекста вы указываете метки для своих объектов.

  • file_contexts присваивает метки файлам и используется различными компонентами пользовательского пространства. При создании новых политик создавайте или обновляйте этот файл, чтобы присваивать файлам новые метки. Чтобы применить новые file_contexts , пересоберите образ файловой системы или запустите restorecon для файла, которому нужно присвоить новую метку. При обновлении изменения в file_contexts автоматически применяются к системному разделу и разделу пользовательских данных в рамках обновления. Изменения также могут быть автоматически применены при обновлении к другим разделам путем добавления вызовов restorecon_recursive в файл board после монтирования раздела в режиме чтения-записи.
  • genfs_contexts присваивает метки файловым системам, таким как proc или vfat , которые не поддерживают расширенные атрибуты. Эта конфигурация загружается как часть политики ядра, но изменения могут не вступить в силу для inode-узлов в ядре, что потребует перезагрузки или отмонтирования и повторного монтирования файловой системы для полного применения изменений. Конкретные метки также могут быть присвоены конкретным точкам монтирования, например, vfat с помощью параметра context=mount .
  • property_contexts присваивает метки системным свойствам Android, определяя, какие процессы могут их устанавливать. Эта конфигурация считывается процессом init во время запуска.
  • service_contexts присваивает метки службам Android Binder, контролируя, какие процессы могут добавлять (регистрировать) и находить (искать) ссылку на службу Binder. Эта конфигурация считывается процессом servicemanager во время запуска.
  • seapp_contexts присваивает метки процессам приложения и каталогам /data/data . Эта конфигурация считывается процессом zygote при каждом запуске приложения, а также installd во время запуска системы.
  • Файл mac_permissions.xml присваивает приложениям тег seinfo на основе их сигнатуры и, при необходимости, имени пакета. Затем тег seinfo может использоваться в качестве ключа в файле seapp_contexts для присвоения определенной метки всем приложениям с этим тегом seinfo . Эта конфигурация считывается system_server во время запуска.
  • keystore2_key_contexts присваивает метки пространствам имен Keystore 2. Эти пространства имен обеспечиваются демоном keystore2 . Keystore всегда предоставлял пространства имен на основе UID/AID. Keystore 2 дополнительно обеспечивает соблюдение пространств имен, определенных sepolicy. Подробное описание формата и соглашений этого файла можно найти здесь .

Файл сборки BoardConfig.mk

После редактирования или добавления файлов политик и контекста обновите файл makefile /device/ manufacturer / device-name /BoardConfig.mk указав в нем подкаталог sepolicy и каждый новый файл политики. Дополнительную информацию о переменных BOARD_SEPOLICY см. в файле system/sepolicy/README .

BOARD_SEPOLICY_DIRS += \
        <root>/device/manufacturer/device-name/sepolicy

BOARD_SEPOLICY_UNION += \
        genfs_contexts \
        file_contexts \
        sepolicy.te

После переустановки на вашем устройстве будет включен SELinux. Теперь вы можете либо настроить политики SELinux в соответствии с вашими собственными дополнениями к операционной системе Android, как описано в разделе «Настройка» , либо проверить существующую конфигурацию, как описано в разделе «Проверка» .

После установки новых файлов политик и обновлений BoardConfig.mk новые параметры политик автоматически включаются в окончательный файл политик ядра. Дополнительную информацию о том, как создается sepolicy на устройстве, см. в разделе «Создание sepolicy» .

Выполнение

Чтобы начать работу с SELinux:

  1. Включить SELinux в ядре: CONFIG_SECURITY_SELINUX=y
  2. Измените параметр kernel_cmdline или bootconfig следующим образом:
    BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
    или
    BOARD_BOOTCONFIG := androidboot.selinux=permissive
    Это необходимо только для первоначальной разработки политики для устройства. После создания первоначальной политики загрузки удалите этот параметр, чтобы устройство могло применять правила или чтобы проверка CTS завершилась неудачей.
  3. Загрузите систему в разрешающем режиме и посмотрите, какие отказы будут обнаружены при загрузке:
    В Ubuntu 14.04 или более новых версиях:
    adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
    
    На Ubuntu 12.04:
    adb pull /sys/fs/selinux/policy
    adb logcat -b all | audit2allow -p policy
    
  4. Проанализируйте вывод на наличие предупреждений, похожих на init: Warning! Service name needs a SELinux domain defined; please fix! See Validation for instructions and tools.
  5. Определите устройства и другие новые файлы, требующие маркировки.
  6. Используйте существующие или новые метки для ваших объектов. Изучите файлы *_contexts , чтобы увидеть, как объекты были помечены ранее, и, используя знание значений меток, назначьте новую. В идеале это должна быть существующая метка, соответствующая политике, но иногда требуется новая метка и правила доступа к ней. Добавьте ваши метки в соответствующие файлы контекста.
  7. Определите домены/процессы, для которых необходимы собственные домены безопасности. Вероятно, вам потребуется написать совершенно новую политику для каждого из них. Например, все службы, запущенные из init , должны иметь свои собственные домены. Следующие команды помогут выявить те, которые остаются запущенными (но ВСЕ службы нуждаются в такой обработке):
    adb shell su -c ps -Z | grep init
    
    adb shell su -c dmesg | grep 'avc: '
    
  8. Просмотрите init. device .rc чтобы выявить домены, для которых не указан тип домена. Присвойте им домен на раннем этапе разработки, чтобы избежать добавления правил в init или путаницы между доступом к init и init , предусмотренным в их собственной политике.
  9. Настройте файл BOARD_CONFIG.mk для использования переменных BOARD_SEPOLICY_* . Подробности настройки см. в файле README в system/sepolicy .
  10. Изучите файлы device и device и убедитесь, что каждое использование mount соответствует правильно обозначенной файловой системе или что указана опция context= mount .
  11. Проанализируйте каждое отклонение и создайте политику SELinux для корректной обработки каждого из них. Примеры см. в разделе «Настройка» .

Начать следует с политик, представленных в AOSP, а затем дополнять их собственными настройками. Более подробную информацию о стратегии применения политик и более детальное рассмотрение некоторых из этих шагов см. в разделе «Написание политик SELinux» .

Варианты использования

Вот конкретные примеры уязвимостей, которые следует учитывать при разработке собственного программного обеспечения и соответствующих политик SELinux:

Символические ссылки: Поскольку символические ссылки отображаются как файлы, их часто считывают как файлы, что может привести к уязвимостям. Например, некоторые привилегированные компоненты, такие как init , изменяют права доступа к определенным файлам, иногда делая их чрезмерно открытыми.

Затем злоумышленники могут заменить эти файлы символическими ссылками на контролируемый ими код, что позволит им перезаписывать произвольные файлы. Но если вы знаете, что ваше приложение никогда не использует символические ссылки, вы можете запретить это с помощью SELinux.

Системные файлы: Рассмотрим класс системных файлов, которые должны изменяться только системным сервером. Тем не менее, поскольку netd , init и vold работают от имени root, они могут получить доступ к этим системным файлам. Таким образом, если netd будет скомпрометирован, это может поставить под угрозу эти файлы и потенциально сам системный сервер.

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

Данные приложения: Еще один пример — это класс функций, которые должны выполняться от имени root, но не должны иметь доступа к данным приложения. Это невероятно полезно, поскольку можно делать самые разные заявления, например, запрещать доступ к интернету определенным доменам, не связанным с данными приложения.

setattr: Для таких команд, как chmod и chown , можно определить набор файлов, для которых соответствующий домен может выполнять setattr . Любые файлы за пределами этого набора могут быть запрещены для этих изменений, даже для пользователей с правами root. Таким образом, приложение может запускать chmod и chown для файлов с метками app_data_files , но не shell_data_files или system_data_files .