Реализация SELinux

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

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

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

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

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

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

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

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

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

Make-файл BoardConfig.mk

После редактирования или добавления файлов политики и контекста обновите make-файл /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! Инструкции и инструменты см. в разделе «Проверка» .
  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 с теми, которые указаны в их собственной политике.
  9. Настройте BOARD_CONFIG.mk для использования переменных BOARD_SEPOLICY_* . Подробную информацию о настройке см . в README в system/sepolicy .
  10. Проверьте инициализацию. device .rc и fstab. файл 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 .